home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / modes / verilog-mode.el.z / verilog-mode.el
Encoding:
Text File  |  1998-05-21  |  102.0 KB  |  3,310 lines

  1. ;;; verilog-mode.el --- major mode for editing verilog source in Emacs
  2. ;;
  3. ;; $Header: /home/mac/emacs/lisp/verilog-mode.el,v 2.25 1997/04/15 23:35:59 mac Exp $
  4.  
  5. ;; Copyright (C) 1996 Free Software Foundation, Inc.
  6.  
  7. ;; Author: Michael McNamara (mac@silicon-sorcery.com) 
  8. ;; President, Silicon Sorcery
  9. ;; Keywords: languages
  10.  
  11. ;; This file is part of GNU Emacs.
  12.  
  13. ;; This program is free software; you can redistribute it and/or modify
  14. ;; it under the terms of the GNU General Public License as published by
  15. ;; the Free Software Foundation; either version 2 of the License, or
  16. ;; (at your option) any later version.
  17.  
  18. ;; This program is distributed in the hope that it will be useful,
  19. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. ;; GNU General Public License for more details.
  22.  
  23. ;; You should have received a copy of the GNU General Public License
  24. ;; along with this program; if not, write to the Free Software
  25. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  
  27. ;;; Commentary:
  28.  
  29. ;;; This mode borrows heavily from the pascal-mode and the cc-mode of emacs
  30.  
  31. ;;; USAGE
  32. ;;; =====
  33.  
  34. ;;; A major mode for editing Verilog HDL source code. When you have
  35. ;;; entered Verilog mode, you may get more info by pressing C-h m. You
  36. ;;; may also get online help describing various functions by: C-h f
  37. ;;; <Name of function you want described>
  38.  
  39. ;;; To set up automatic verilog mode, put this file in your load path,
  40. ;;; and include stuff like this in your .emacs:
  41.  
  42. ; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
  43. ; (setq auto-mode-alist (cons  '("\\.v\\'" . verilog-mode) auto-mode-alist))
  44. ; (setq auto-mode-alist (cons  '("\\.dv\\'" . verilog-mode) auto-mode-alist))
  45.  
  46. ;;; If you want to customize Verilog mode to fit your needs better,
  47. ;;; you may add these lines (the values of the variables presented
  48. ;;; here are the defaults):
  49. ;;;
  50. ;;; ;; User customization for Verilog mode
  51. ;;; (setq verilog-indent-level             3
  52. ;;;       verilog-indent-level-module      3
  53. ;;;       verilog-indent-level-declaration 3
  54. ;;;       verilog-indent-level-behavorial  3
  55. ;;;       verilog-case-indent              2
  56. ;;;       verilog-auto-newline             t
  57. ;;;       verilog-auto-indent-on-newline   t
  58. ;;;       verilog-tab-always-indent        t
  59. ;;;       verilog-auto-endcomments         t
  60. ;;;       verilog-minimum-comment-distance 40
  61. ;;;       verilog-indent-begin-after-if    t
  62. ;;;       verilog-auto-lineup              '(all))
  63.  
  64. ;;; KNOWN BUGS / BUGREPORTS
  65. ;;; ======================= This is beta code, and likely has
  66. ;;; bugs. Please report any and all bugs to me at mac@silicon-sorcery.com.
  67. ;; 
  68. ;;; Code:
  69.  
  70. (provide 'verilog-mode)
  71.  
  72. ;; This variable will always hold the version number of the mode
  73. (defconst verilog-mode-version "$$Revision: 2.25 $$"
  74.   "Version of this verilog mode.")
  75.  
  76. ;;
  77. ;; A hack so we can support either custom, or the old defvar
  78. ;;
  79. (eval-and-compile
  80.   (condition-case ()
  81.       (require 'custom)
  82.     (error nil))
  83.   (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
  84.       nil ;; We've got what we needed
  85.     ;; We have the old custom-library, hack around it!
  86.     (defmacro defgroup (&rest args)
  87.       nil)
  88.     (defmacro customize (&rest args)
  89.       (message "Sorry, Customise is not available with this version of emacs"))
  90.     (defmacro defcustom (var value doc &rest args) 
  91.       (` (defvar (, var) (, value) (, doc))))))
  92.  
  93. (defun verilog-customize ()
  94.   "Link to customize screen for Verilog"
  95.   (interactive)
  96.   (customize 'verilog)
  97.   )
  98.  
  99. (defgroup verilog nil
  100.   "Faciliates easy editing of Verilog source text"
  101.   :group 'languages)
  102.       
  103. (defcustom verilog-indent-level 3
  104.   "*Indentation of Verilog statements with respect to containing block."
  105.   :group 'verilog
  106.   :type 'integer 
  107.   )
  108.  
  109. (defcustom verilog-indent-level-module 3
  110.   "* Indentation of Module level Verilog statements. (eg always, initial)
  111.     Set to 0 to get initial and always statements lined up 
  112.     on the left side of your screen."
  113.   :group 'verilog
  114.   :type 'integer 
  115.   )
  116.  
  117. (defcustom verilog-indent-level-declaration 3
  118.   "*Indentation of declarations with respect to containing block. 
  119.     Set to 0 to get them list right under containing block."
  120.   :group 'verilog
  121.   :type 'integer 
  122.   )
  123.  
  124. (defcustom verilog-indent-level-behavorial 3
  125.   "*Absolute indentation of first begin in a task or function block
  126.     Set to 0 to get such code to start at the left side of the screen."
  127.   :group 'verilog
  128.   :type 'integer 
  129.   )
  130.  
  131. (defcustom verilog-cexp-indent 1
  132.   "*Indentation of Verilog statements split across lines."
  133.   :group 'verilog
  134.   :type 'integer 
  135.   )
  136.  
  137. (defcustom verilog-case-indent 2
  138.   "*Indentation for case statements."
  139.   :group 'verilog
  140.   :type 'integer 
  141.   )
  142.  
  143. (defcustom verilog-auto-newline t
  144.   "*Non-nil means automatically newline after semicolons"
  145.   :group 'verilog
  146.   :type 'integer 
  147.   )
  148.  
  149. (defcustom verilog-auto-indent-on-newline t
  150.   "*Non-nil means automatically indent line after newline"
  151.   :group 'verilog
  152.   :type 'integer 
  153.   )
  154.  
  155. (defcustom verilog-tab-always-indent t
  156.   "*Non-nil means TAB in Verilog mode should always reindent the
  157.   current line, regardless of where in the line point is when the TAB
  158.   command is used."
  159.   :group 'verilog
  160.   :type 'integer 
  161.   )
  162.  
  163. (defcustom verilog-indent-begin-after-if t
  164.   "*If true, indent begin statements following if, else, while, for
  165.   and repeat.  otherwise, line them up."
  166.   :group 'verilog
  167.   :type 'boolean )
  168.  
  169. (defcustom verilog-auto-endcomments t
  170.   "*Non-nil means a comment /* ... */ is set after the ends which ends
  171.   cases and functions. The name of the function or case will be set
  172.   between the braces."
  173.   :group 'verilog
  174.   :type 'boolean )
  175.  
  176. (defcustom verilog-minimum-comment-distance 40
  177.   "*Minimum distance between begin and end required before a comment
  178.   will be inserted.  Setting this variable to zero results in every
  179.   end aquiring a comment; the default avoids too many redundanet
  180.   comments in tight quarters"
  181.   :group 'verilog
  182.   :type 'integer 
  183.   )
  184.  
  185. (defvar verilog-auto-lineup '(all) 
  186.   "*List of contexts where auto lineup of :'s or ='s should be done.
  187. Elements can be of type: 'declaration' or 'case', which will do auto
  188. lineup in declarations or case-statements respectively. The word 'all'
  189. will do all lineups. '(case declaration) for instance will do lineup
  190. in case-statements and parameterlist, while '(all) will do all
  191. lineups."
  192.   )
  193.  
  194. (defvar verilog-mode-abbrev-table nil
  195.   "Abbrev table in use in Verilog-mode buffers.")
  196.  
  197. (defvar verilog-font-lock-keywords-after-1930
  198.   '(
  199.     ;;
  200.    ("^\\s-*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>"  
  201.     1 font-lock-keyword-face) 
  202.    ("^\\s-*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>\\s-*\\(\\sw+\\)"  
  203.     2 font-lock-function-name-face nil t)
  204.    ("\\\\\\s-*" 0 'font-lock-function-name-face)  
  205.    ("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9\]+\\('[hdxbo][0-9_xz]*\\)?\\)\\|\\((\[^)\]*)\\|\\sw+\\)\\)\\)" 0 font-lock-type-face)
  206.    ("\\(`\\s-*[A-Za-z][A-Za-z0-9_]*\\)"  0 font-lock-type-face)  
  207.    ("\\<\\(in\\(teger\\|put\\|out\\)\\|parameter\\|defparam\\|output\\|supply[01]?\\|event\\|tri\\(0\\|1\\|reg\\|and\\|or\\)?\\|w\\(ire\\|or\\|and\\)\\|time\\|re\\(al\\(time\\)?\\|g\\)\\)\\>" 
  208.     0 font-lock-type-face)  
  209.    ("\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\)\\|\\(\\<\\(begin\\|case[xz]?\\|end\\(case\\|function\\|task\\|module\\|table\\|primitive\\|specify\\)?\\|a\\(ssign\\|lways\\)\\|default\\|initial\\|table\\|\\(pos\\|neg\\)edge\\|else\\|for\\(ever\\|k\\)?\\|join\\|if\\|repeat\\|then\\|while\\|specify\\)\\>\\)" 
  210.      0 font-lock-keyword-face)
  211.    )
  212. )
  213.  
  214. (defvar verilog-font-lock-keywords-before-1930
  215.   '(
  216.     ("^\\s-*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>"  . 1)
  217.     ("^\\s-*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>\\s-*\\(\\sw+\\)"  
  218.      2 font-lock-function-name-face nil t)
  219.     ("\\(\\\\\\s-*\\)\\|\\(`[ \t]*[A-Za-z][A-Za-z0-9_]*\\)" 0 font-lock-function-name-face)
  220.     ("[@#]" . font-lock-type-face)
  221.     ("\\<\\(in\\(teger\\|put\\|out\\)\\|parameter\\|defparam\\|output\\|supply[01]?\\|event\\|tri\\(0\\|1\\|reg\\|and\\|or\\)?\\|w\\(ire\\|or\\|and\\)\\|time\\|re\\(al\\(time\\)?\\|g\\)\\)\\>" 
  222.      0 font-lock-type-face)
  223.     ("\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\)\\|\\(\\<\\(begin\\|case[xz]?\\|end\\(case\\|function\\|task\\|module\\|table\\|primitive\\|specify\\)?\\|a\\(ssign\\|lways\\)\\|default\\|initial\\|table\\|\\(pos\\|neg\\)edge\\|else\\|for\\(ever\\|k\\)?\\|join\\|if\\|repeat\\|then\\|while\\|specify\\)\\>\\)" . font-lock-keyword-face)
  224.     )
  225. )
  226.  
  227. ;; Insure we have certain packages
  228.  
  229. (if (fboundp 'eval-when-compile)
  230.     (eval-when-compile
  231.       (condition-case nil
  232.           (require 'imenu)
  233.         (error nil))
  234.       (condition-case nil
  235.       (require 'reporter)
  236.         (error nil))
  237.       (condition-case nil
  238.           (require 'easymenu)
  239.         (error nil))))
  240.  
  241. (defvar verilog-imenu-generic-expression
  242.   '((nil "^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 3)
  243.     ("*Vars*" "^\\s-*\\(reg\\|wire\\)\\)\\s-+\\(\\|\\[[^\\]+]\\s-+\\)\\([-A-Za-z0-9+]+\\)" 3))
  244.   "Imenu expression for Verilog-mode.  See `imenu-generic-expression'.")
  245.  
  246. (defvar verilog-mode-abbrev-table nil
  247.   "Abbrev table in use in Verilog-mode buffers.")
  248.  
  249.  
  250. (define-abbrev-table 'verilog-mode-abbrev-table ())
  251.  
  252. (defvar verilog-mode-map ()
  253.   "Keymap used in Verilog mode.")
  254. (if verilog-mode-map
  255.     ()
  256.   (setq verilog-mode-map (make-sparse-keymap))
  257.   (define-key verilog-mode-map ";"        'electric-verilog-semi)
  258.   (define-key verilog-mode-map ":"        'electric-verilog-colon)
  259.   (define-key verilog-mode-map "="        'electric-verilog-equal)
  260.   (define-key verilog-mode-map "\`"       'electric-verilog-tick)
  261.   (define-key verilog-mode-map "\t"       'electric-verilog-tab)
  262.   (define-key verilog-mode-map "\r"       'electric-verilog-terminate-line)
  263.   (define-key verilog-mode-map "\M-\C-b"  'electric-verilog-backward-sexp)
  264.   (define-key verilog-mode-map "\M-\C-f"  'electric-verilog-forward-sexp)
  265.   (define-key verilog-mode-map "\M-\r"    (function (lambda ()
  266.               (interactive) (electric-verilog-terminate-line 1))))
  267.   (define-key verilog-mode-map "\M-\t"    'verilog-complete-word)
  268.   (define-key verilog-mode-map "\M-?"     'verilog-show-completions)
  269.   (define-key verilog-mode-map "\M-\C-h"  'verilog-mark-defun)
  270.   (define-key verilog-mode-map "\C-c\C-b" 'verilog-insert-block)
  271.   (define-key verilog-mode-map "\C-cb"    'verilog-label-be)
  272.   (define-key verilog-mode-map "\C-ci"    'verilog-pretty-declarations)
  273.   (define-key verilog-mode-map "\C-cC-b"  'verilog-submit-bug-report)
  274.   (define-key verilog-mode-map "\M-*"     'verilog-star-comment)
  275.   (define-key verilog-mode-map "\C-c\C-c" 'verilog-comment-region)
  276.   (define-key verilog-mode-map "\C-c\C-u" 'verilog-uncomment-region)
  277.   (define-key verilog-mode-map "\M-\C-a"  'verilog-beg-of-defun)
  278.   (define-key verilog-mode-map "\M-\C-e"  'verilog-end-of-defun)
  279.   (define-key verilog-mode-map "\C-c\C-d" 'verilog-goto-defun)
  280.   )
  281.  
  282. ;; menus
  283.  
  284. (if (string-match "XEmacs" emacs-version)
  285.     (defvar verilog-xemacs-menu
  286.       '("Verilog"
  287.     ["Line up declarations around point"        verilog-pretty-declarations t]
  288.     ["Redo/insert comments on every end" verilog-label-be t]
  289.     "----"
  290.     ["Beginning of function"     verilog-beg-of-defun t]
  291.     ["End of function"           verilog-end-of-defun t]
  292.     ["Mark function"             verilog-mark-defun t]
  293.     "----"
  294.     ["Move to beginning of block" electric-verilog-backward-sexp t]
  295.     ["Move to end of block"      electric-verilog-forward-sexp t]
  296.     "----" 
  297.     ["Comment Region"            verilog-comment-region t]
  298.     ["UnComment Region"          verilog-uncomment-region t]
  299.     ["Multi-line comment insert" verilog-star-comment t]
  300.     "----" 
  301.     ["Insert begin-end block"    verilog-insert-block t]
  302.     ["Complete word"             verilog-complete-word t]
  303.     "----"
  304.     ["Submit bug report"         verilog-submit-bug-report t]
  305.     ["Customize Verilog Mode..." verilog-customize t]
  306.     "XEmacs menu for VERILOG mode."))
  307.   (progn
  308.     (easy-menu-define verilog-menu verilog-mode-map "Menu for Verilog mode"
  309.               '("Verilog"
  310.             ["Line up declarations around point"        verilog-pretty-declarations t]
  311.             ["Redo/insert comments on every end" verilog-label-be t]
  312.             "----"
  313.             ["Beginning of function"     verilog-beg-of-defun t]
  314.             ["End of function"           verilog-end-of-defun t]
  315.             ["Mark function"             verilog-mark-defun t]
  316.             "----" 
  317.             ["Move to beginning of block" electric-verilog-backward-sexp t]
  318.             ["Move to end of block"      electric-verilog-forward-sexp t]
  319.             "----" 
  320.             ["Comment Region"            verilog-comment-region t]
  321.             ["UnComment Region"          verilog-uncomment-region t]
  322.             ["Multi-line comment insert" verilog-star-comment t]
  323.             "----" 
  324.             ["Insert begin-end block"    verilog-insert-block t]
  325.             ["Complete word"             verilog-complete-word t]
  326.             "----"
  327.             ["Submit bug report"         verilog-submit-bug-report t]
  328.             ["Customize Verilog Mode..." verilog-customize t]
  329.             ))))
  330.  
  331. (defvar verilog-mode-abbrev-table nil
  332.   "Abbrev table in use in Verilog-mode buffers.")
  333.  
  334. (define-abbrev-table 'verilog-mode-abbrev-table ())
  335.  
  336.   
  337. ;;;
  338. ;;; Regular expressions used to calculate indent, etc.
  339. ;;;
  340. (defconst verilog-symbol-re      "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
  341. (defconst verilog-case-re        "\\(\\<case[xz]?\\>\\)")
  342. ;; Want to match
  343. ;; aa :
  344. ;; aa,bb :
  345. ;; a[34:32] :
  346. ;; a,
  347. ;;   b :
  348. (defconst 
  349.   verilog-no-indent-begin-re 
  350.   "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\)\\>")
  351. (defconst verilog-ends-re
  352.   (concat
  353.    "\\(\\<else\\>\\)\\|"
  354.    "\\(\\<if\\>\\)\\|"
  355.    "\\(\\<end\\>\\)\\|"
  356.    "\\(\\<join\\>\\)\\|" 
  357.    "\\(\\<endcase\\>\\)\\|" 
  358.    "\\(\\<endtable\\>\\)\\|" 
  359.    "\\(\\<endspecify\\>\\)\\|" 
  360.    "\\(\\<endfunction\\>\\)\\|"
  361.    "\\(\\<endtask\\>\\)"))
  362.  
  363.  
  364. (defconst verilog-enders-re
  365.   (concat "\\(\\<endcase\\>\\)\\|"
  366.       "\\(\\<end\\>\\)\\|"
  367.       "\\(\\<end\\(\\(function\\)\\|\\(task\\)\\|"
  368.       "\\(module\\)\\|\\(primitive\\)\\)\\>\\)"))
  369. (defconst verilog-endcomment-reason-re 
  370.   (concat 
  371.    "\\(\\<fork\\>\\)\\|"
  372.    "\\(\\<begin\\>\\)\\|"
  373.    "\\(\\<if\\>\\)\\|"
  374.    "\\(\\<else\\>\\)\\|"
  375.    "\\(\\<end\\>.*\\<else\\>\\)\\|"
  376.    "\\(\\<task\\>\\)\\|"
  377.    "\\(\\<function\\>\\)\\|"
  378.    "\\(\\<initial\\>\\)\\|"
  379.    "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
  380.    "\\(\\<while\\>\\)\\|"
  381.    "\\(\\<for\\(ever\\)?\\>\\)\\|"
  382.    "\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
  383.    "#"))
  384.  
  385. (defconst verilog-named-block-re  "begin[ \t]*:")
  386. (defconst verilog-beg-block-re
  387.   ;; "begin" "case" "casex" "fork" "casez" "table" "specify" "function" "task"
  388.   "\\(\\<\\(begin\\>\\|case\\(\\>\\|x\\>\\|z\\>\\)\\|f\\(ork\\>\\|unction\\>\\)\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)")
  389.  
  390. (defconst verilog-beg-block-re-1 
  391.   "\\<\\(begin\\)\\|\\(case[xz]?\\)\\|\\(fork\\)\\|\\(table\\)\\|\\(specify\\)\\|\\(function\\)\\|\\(task\\)\\>")
  392. (defconst verilog-end-block-re   
  393.   ;; "end" "join" "endcase" "endtable" "endspecify" "endtask" "endfunction"
  394.   "\\<\\(end\\(\\>\\|case\\>\\|function\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\|join\\>\\)")
  395.  
  396. (defconst verilog-end-block-re-1 "\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)\\|\\(\\<endtable\\>\\)\\|\\(\\<endspecify\\>\\)\\|\\(\\<endfunction\\>\\)\\|\\(\\<endtask\\>\\)")
  397. (defconst verilog-declaration-re 
  398.   ;; "input" "inout" "output" "integer" "parameter" "defparam" "event" 
  399.   ;; "real" "reg" "realtime" "time" "tri" "tri0" "tri1" "trireg" "triand" 
  400.   ;; "trior" "supply0" "supply1" "wire" "wor" "wand"
  401. "\\(\\<\\(defparam\\>\\|event\\>\\|in\\(out\\>\\|put\\>\\|teger\\>\\)\\|output\\>\\|parameter\\>\\|re\\(al\\(\\>\\|time\\>\\)\\|g\\>\\)\\|supply\\(0\\>\\|1\\>\\)\\|t\\(ime\\>\\|ri\\(0\\>\\|1\\>\\|\\>\\|and\\>\\|or\\>\\|reg\\>\\)\\)\\|w\\(and\\>\\|ire\\>\\|or\\>\\)\\)\\)")
  402. (defconst verilog-declaration-re-1 (concat "^[ \t]*" verilog-declaration-re "[ \t]*\\(\\[[^]]*\\][ \t]*\\)?"))
  403. (defconst verilog-declaration-re-2 (concat "[ \t]*" verilog-declaration-re "[ \t]*\\(\\[[^]]*\\][ \t]*\\)?"))
  404. (defconst verilog-defun-re 
  405.   ;;"module" "macromodule" "primitive"
  406.   "\\(\\<\\(m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)")
  407. (defconst verilog-end-defun-re   
  408.   ;; "endmodule" "endprimitive"
  409. "\\(\\<end\\(module\\>\\|primitive\\>\\)\\)")
  410. (defconst verilog-zero-indent-re 
  411.   (concat verilog-defun-re "\\|" verilog-end-defun-re))
  412. (defconst verilog-directive-re
  413.   ;;   "`else" "`ifdef" "`endif" "`define" "`undef" "`include"
  414.   "\\(\\<`\\(define\\>\\|e\\(lse\\>\\|ndif\\>\\)\\|i\\(fdef\\>\\|nclude\\>\\)\\|undef\\>\\)\\)")
  415. (defconst verilog-autoindent-lines-re
  416.   ;; "macromodule" "module" "primitive" "end" "endcase" "endfunction"
  417.   ;; "endtask" "endmodule" "endprimitive" "endspecify" "endtable" "join" 
  418.   ;; "begin" "else" "`else" "`ifdef" "`endif" "`define" "`undef" "`include"
  419.   "\\(\\<\\(`\\(define\\>\\|e\\(lse\\>\\|ndif\\>\\)\\|i\\(fdef\\>\\|nclude\\>\\)\\|undef\\>\\)\\|begin\\>\\|e\\(lse\\>\\|nd\\(\\>\\|case\\>\\|function\\>\\|module\\>\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)\\|join\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)")
  420.  
  421. (defconst verilog-behavorial-block-beg-re
  422.   "\\(\\<initial\\>\\|\\<always\\>\\|\\<function\\>\\|\\<task\\>\\)")
  423. (defconst verilog-indent-reg 
  424.   (concat 
  425.    "\\(\\<begin\\>\\|\\<case[xz]?\\>\\|\\<specify\\>\\|\\<fork\\>\\|\\<table\\>\\)\\|"
  426.    "\\(\\<end\\>\\|\\<join\\>\\|\\<endcase\\>\\|\\<endtable\\>\\|\\<endspecify\\>\\)\\|" 
  427.    "\\(\\<module\\>\\|\\<macromodule\\>\\|\\<primitive\\>\\|\\<initial\\>\\|\\<always\\>\\)\\|"
  428.    "\\(\\<endmodule\\>\\|\\<endprimitive\\>\\)\\|"
  429.    "\\(\\<endtask\\>\\|\\<endfunction\\>\\)\\|"
  430.    "\\(\\<function\\>\\|\\<task\\>\\)"      
  431.    ;;      "\\|\\(\\<if\\>\\|\\<else\\>\\)"
  432.    ))
  433. (defconst verilog-indent-re 
  434.   "\\(\\<\\(always\\>\\|begin\\>\\|case\\(\\>\\|x\\>\\|z\\>\\)\\|end\\(\\>\\|case\\>\\|function\\>\\|module\\>\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\|f\\(ork\\>\\|unction\\>\\)\\|initial\\>\\|join\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)")
  435.  
  436. (defconst verilog-defun-level-re 
  437.   ;; "module" "macromodule" "primitive" "initial" "always" "endtask" "endfunction"
  438.   "\\(\\<\\(always\\>\\|end\\(function\\>\\|task\\>\\)\\|initial\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)")
  439. (defconst verilog-cpp-level-re 
  440.  ;;"endmodule" "endprimitive"
  441.   "\\(\\<end\\(module\\>\\|primitive\\>\\)\\)")
  442. (defconst verilog-behavorial-level-re
  443.   ;; "function" "task"
  444.   "\\(\\<\\(function\\>\\|task\\>\\)\\)")
  445. (defconst verilog-complete-reg
  446.   ;; "always" "repeat" "case" "casex" "casez" "while" "if" "for" "forever"
  447.   "\\(\\<\\(always\\>\\|case\\(\\>\\|x\\>\\|z\\>\\)\\|else\\|for\\(\\>\\|ever\\>\\)\\|if\\>\\|repeat\\>\\|while\\>\\)\\)")
  448. (defconst verilog-end-statement-re 
  449.   (concat "\\(" verilog-beg-block-re "\\)\\|\\("
  450.       verilog-end-block-re "\\)"))
  451. (defconst verilog-endcase-re 
  452.   (concat verilog-case-re "\\|" 
  453.       "\\(endcase\\)\\|"
  454.       verilog-defun-re
  455.       ))
  456. ;;; Strings used to mark beginning and end of excluded text
  457. (defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----")
  458. (defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */")
  459.  
  460. (defconst verilog-emacs-features
  461.   (let ((major (and (boundp 'emacs-major-version)
  462.             emacs-major-version))
  463.     (minor (and (boundp 'emacs-minor-version)
  464.             emacs-minor-version))
  465.     flavor comments)
  466.     ;; figure out version numbers if not already discovered
  467.     (and (or (not major) (not minor))
  468.      (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
  469.      (setq major (string-to-int (substring emacs-version
  470.                            (match-beginning 1)
  471.                            (match-end 1)))
  472.            minor (string-to-int (substring emacs-version
  473.                            (match-beginning 2)
  474.                            (match-end 2)))))
  475.     (if (not (and major minor))
  476.     (error "Cannot figure out the major and minor version numbers."))
  477.     ;; calculate the major version
  478.     (cond
  479.      ((= major 18) (setq major 'v18))    ;Emacs 18
  480.      ((= major 4)  (setq major 'v18))    ;Epoch 4
  481.      ((= major 20) (setq major 'v20
  482.              flavor 'XEmacs))
  483.      ((= major 19) (setq major 'v19    ;Emacs 19
  484.              flavor (if (or (string-match "Lucid" emacs-version)
  485.                     (string-match "XEmacs" emacs-version))
  486.                     'XEmacs 'FSF)))
  487.      ;; I don't know
  488.      (t (error "Cannot recognize major version number: %s" major)))
  489.     ;; XEmacs 19 uses 8-bit modify-syntax-entry flags, as do all
  490.     ;; patched Emacs 19, Emacs 18, Epoch 4's.  Only Emacs 19 uses a
  491.     ;; 1-bit flag.  Let's be as smart as we can about figuring this
  492.     ;; out.
  493.     (if (or (eq major 'v20) (eq major 'v19))
  494.     (let ((table (copy-syntax-table)))
  495.       (modify-syntax-entry ?a ". 12345678" table)
  496.       (cond
  497.        ;; XEmacs pre 20 and Emacs pre 19.30 use vectors for syntax tables.
  498.        ((vectorp table)
  499.         (if (= (logand (lsh (aref table ?a) -16) 255) 255)
  500.         (setq comments '8-bit)
  501.           (setq comments '1-bit)))
  502.        ;; XEmacs 20 is known to be 8-bit
  503.        ((eq flavor 'XEmacs) (setq comments '8-bit))
  504.        ;; Emacs 19.30 and beyond are known to be 1-bit
  505.        ((eq flavor 'FSF) (setq comments '1-bit))
  506.        ;; Don't know what this is
  507.        (t (error "Couldn't figure out syntax table format."))
  508.        ))
  509.       ;; Emacs 18 has no support for dual comments
  510.       (setq comments 'no-dual-comments))
  511.     ;; lets do some minimal sanity checking.
  512.     (if (or
  513.      ;; Lemacs before 19.6 had bugs
  514.      (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
  515.      ;; Emacs 19 before 19.21 has known bugs
  516.      (and (eq major 'v19) (eq flavor 'FSF) (< minor 21))
  517.      )
  518.     (with-output-to-temp-buffer "*verilog-mode warnings*"
  519.       (print (format
  520. "The version of Emacs that you are running, %s,
  521. has known bugs in its syntax parsing routines which will affect the
  522. performance of verilog-mode. You should strongly consider upgrading to the
  523. latest available version.  verilog-mode may continue to work, after a
  524. fashion, but strange indentation errors could be encountered."
  525.              emacs-version))))
  526.     ;; Emacs 18, with no patch is not too good
  527.     (if (and (eq major 'v18) (eq comments 'no-dual-comments))
  528.     (with-output-to-temp-buffer "*verilog-mode warnings*"
  529.       (print (format
  530. "The version of Emacs 18 you are running, %s,
  531. has known deficiencies in its ability to handle the dual verilog 
  532. (and C++) comments, (e.g. the // and /* */ comments). This will
  533. not be much of a problem for you if you only use the /* */ comments,
  534. but you really should strongly consider upgrading to one of the latest 
  535. Emacs 19's.  In Emacs 18, you may also experience performance degradations. 
  536. Emacs 19 has some new built-in routines which will speed things up for you.
  537. Because of these inherent problems, verilog-mode is not supported 
  538. on emacs-18."
  539.                 emacs-version))))
  540.     ;; Emacs 18 with the syntax patches are no longer supported
  541.     (if (and (eq major 'v18) (not (eq comments 'no-dual-comments)))
  542.     (with-output-to-temp-buffer "*verilog-mode warnings*"
  543.       (print (format
  544. "You are running a syntax patched Emacs 18 variant.  While this should
  545. work for you, you may want to consider upgrading to Emacs 19.
  546. The syntax patches are no longer supported either for verilog-mode."))))
  547.     (list major comments))
  548.   "A list of features extant in the Emacs you are using.
  549. There are many flavors of Emacs out there, each with different
  550. features supporting those needed by verilog-mode.  Here's the current
  551. supported list, along with the values for this variable:
  552.  
  553.  Vanilla Emacs 18/Epoch 4:   (v18 no-dual-comments)
  554.  Emacs 18/Epoch 4 (patch2):  (v18 8-bit)
  555.  XEmacs (formerly Lucid) 19: (v19 8-bit)
  556.  XEmacs 20:                  (v20 8-bit)
  557.  Emacs 19:                   (v19 1-bit).")
  558.  
  559. (defconst verilog-comment-start-regexp "//\\|/\\*"
  560.   "Dual comment value for `comment-start-regexp'.")
  561.  
  562. (defun verilog-populate-syntax-table (table)
  563.   ;; Populate the syntax TABLE
  564.   ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
  565.   (modify-syntax-entry ?\\ "\\" table)
  566.   (modify-syntax-entry ?+ "." table)
  567.   (modify-syntax-entry ?- "." table)
  568.   (modify-syntax-entry ?= "." table)
  569.   (modify-syntax-entry ?% "." table)
  570.   (modify-syntax-entry ?< "." table)
  571.   (modify-syntax-entry ?> "." table)
  572.   (modify-syntax-entry ?& "." table)
  573.   (modify-syntax-entry ?| "." table)
  574.   (modify-syntax-entry ?_ "w" table)
  575.   (modify-syntax-entry ?\' "." table)
  576. )
  577.  
  578. (defun verilog-setup-dual-comments (table)
  579.   ;; Set up TABLE to handle block and line style comments
  580.   (cond
  581.    ((memq '8-bit verilog-emacs-features)
  582.     ;; XEmacs (formerly Lucid) has the best implementation
  583.     (modify-syntax-entry ?/  ". 1456" table)
  584.     (modify-syntax-entry ?*  ". 23"   table)
  585.     (modify-syntax-entry ?\n "> b"    table)
  586.     ;; Give CR the same syntax as newline, for selective-display
  587.     (modify-syntax-entry ?\^m "> b"    table))
  588.    ((memq '1-bit verilog-emacs-features)
  589.     ;; Emacs 19 does things differently, but we can work with it
  590.     (modify-syntax-entry ?/  ". 124b" table)
  591.     (modify-syntax-entry ?*  ". 23"   table)
  592.     (modify-syntax-entry ?\n "> b"    table)
  593.     ;; Give CR the same syntax as newline, for selective-display
  594.     (modify-syntax-entry ?\^m "> b"   table))
  595.    ))
  596.  
  597. (defvar verilog-mode-syntax-table nil
  598.   "Syntax table used in verilog-mode buffers.")
  599. (if verilog-mode-syntax-table
  600.     ()
  601.   (setq verilog-mode-syntax-table (make-syntax-table))
  602.   (verilog-populate-syntax-table verilog-mode-syntax-table)
  603.   ;; add extra comment syntax
  604.   (verilog-setup-dual-comments verilog-mode-syntax-table)
  605.   )
  606.  
  607. (defvar verilog-font-lock-keywords nil
  608.   "keyword highlighting used in verilog-mode buffers.")
  609. (defvar verilog-font-lock-keywords-1 nil
  610.   "keyword highlighting used in verilog-mode buffers.")
  611. (defvar verilog-font-lock-keywords-2 nil
  612.   "keyword highlighting used in verilog-mode buffers.")
  613. (defvar verilog-font-lock-keywords-3 nil
  614.   "keyword highlighting used in verilog-mode buffers.")
  615. (defvar verilog-font-lock-keywords-4 nil
  616.   "keyword highlighting used in verilog-mode buffers.")
  617. (if verilog-font-lock-keywords
  618.     ()
  619.   (cond
  620.    ;; We can assume 8-bit syntax table emacsen aupport new syntax
  621.    ((memq '8-bit verilog-emacs-features)
  622.     (setq verilog-font-lock-keywords verilog-font-lock-keywords-after-1930
  623.       verilog-font-lock-keywords-1 verilog-font-lock-keywords-after-1930
  624.       verilog-font-lock-keywords-2 verilog-font-lock-keywords-after-1930
  625.       verilog-font-lock-keywords-3 verilog-font-lock-keywords-after-1930
  626.       verilog-font-lock-keywords-4 verilog-font-lock-keywords-after-1930)
  627.     )
  628.    (t
  629.     (setq verilog-font-lock-keywords   verilog-font-lock-keywords-before-1930
  630.       verilog-font-lock-keywords-1 verilog-font-lock-keywords-before-1930
  631.       verilog-font-lock-keywords-2 verilog-font-lock-keywords-before-1930
  632.       verilog-font-lock-keywords-3 verilog-font-lock-keywords-before-1930
  633.       verilog-font-lock-keywords-4 verilog-font-lock-keywords-before-1930)
  634.     )
  635.    )
  636.   )
  637.  
  638. ;;;
  639. ;;;  Macros
  640. ;;;
  641.  
  642. (defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
  643.   "Like re-search-forward, but skips over matches in comments or strings"
  644.   (set-match-data '(nil nil))    
  645.   (while (and
  646.       (re-search-forward REGEXP BOUND NOERROR)
  647.       (and (verilog-skip-forward-comment-or-string)
  648.            (progn 
  649.          (store-match-data '(nil nil))
  650.          (if BOUND
  651.              (< (point) BOUND)
  652.            t)
  653.          )
  654.            )
  655.       )
  656.     )
  657.   (match-end 0))
  658.  
  659. (defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
  660.   "Like re-search-backward, but skips over matches in comments or strings"
  661.   (set-match-data '(nil nil))
  662.   (while (and
  663.       (re-search-backward REGEXP BOUND NOERROR)
  664.       (verilog-skip-backward-comment-or-string)
  665.       (not (set-match-data '(nil nil))))
  666.     ())
  667.   (match-end 0))
  668.  
  669. (defsubst verilog-get-beg-of-line (&optional arg)
  670.   (save-excursion
  671.     (beginning-of-line arg)
  672.     (point)))
  673.  
  674. (defsubst verilog-get-end-of-line (&optional arg)
  675.   (save-excursion
  676.     (end-of-line arg)
  677.     (point)))
  678.  
  679. (defun verilog-declaration-end ()
  680.   (search-forward ";"))
  681.  
  682. (defun electric-verilog-backward-sexp ()
  683.   "Move backward over a sexp"
  684.   (interactive)
  685.   ;; before that see if we are in a comment
  686.   (verilog-backward-sexp)
  687. )
  688. (defun electric-verilog-forward-sexp ()
  689.   "Move backward over a sexp"
  690.   (interactive)
  691.   ;; before that see if we are in a comment
  692.   (verilog-forward-sexp)
  693. )
  694.  
  695. (defun verilog-backward-sexp ()
  696.   (let ((reg)
  697.     (elsec 1)
  698.     (found nil)
  699.     )
  700.     (if (not (looking-at "\\<"))
  701.     (forward-word -1))
  702.     (cond
  703.      ((verilog-skip-backward-comment-or-string)
  704.       )
  705.      ((looking-at "\\<else\\>")
  706.       (setq reg (concat
  707.          verilog-end-block-re
  708.          "\\|\\(\\<else\\>\\)"
  709.          "\\|\\(\\<if\\>\\)"
  710.          ))
  711.       (while (and (not found)
  712.           (verilog-re-search-backward reg nil 'move))
  713.     (cond 
  714.      ((match-end 1) ; endblock
  715.     ; try to leap back to matching outward block by striding across
  716.     ; indent level changing tokens then immediately
  717.     ; previous line governs indentation.
  718.       (verilog-leap-to-head)
  719.       )
  720.      ((match-end 2) ; else, we're in deep
  721.       (setq elsec (1+ elsec))                 
  722.       )
  723.      ((match-end 3) ; found it
  724.       (setq elsec (1- elsec))
  725.       (if (= 0 elsec)
  726.           ;; Now previous line describes syntax
  727.           (setq found 't)
  728.         ))
  729.      )
  730.     )
  731.       )
  732.      ((looking-at verilog-end-block-re)
  733.       (verilog-leap-to-head)
  734.       )
  735.      ((looking-at "\\(endmodule\\>\\)\\|\\(\\<endprimitive\\>\\)")
  736.       (cond
  737.        ((match-end 1)
  738.     (verilog-re-search-backward "\\<\\(macro\\)?module\\>" nil 'move))
  739.        ((match-end 2)
  740.     (verilog-re-search-backward "\\<primitive\\>" nil 'move))
  741.        (t 
  742.     (backward-sexp 1))))
  743.      (t
  744.       (backward-sexp))
  745.      ) ;; cond
  746.     )
  747.   )
  748. (defun verilog-forward-sexp ()
  749.   (let ((reg)
  750.     (st (point)))
  751.     (if (not (looking-at "\\<"))
  752.     (forward-word -1))
  753.     (cond
  754.      ((verilog-skip-forward-comment-or-string)
  755.       (verilog-forward-syntactic-ws)
  756.       )
  757.      ((looking-at verilog-beg-block-re-1);; begin|fork|case|table|specify
  758.       (cond 
  759.        ((match-end 1) ; end
  760.     ;; Search forward for matching begin
  761.     (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" )
  762.     )
  763.        ((match-end 2) ; endcase
  764.     ;; Search forward for matching case
  765.     (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
  766.     )
  767.        ((match-end 3) ; join
  768.     ;; Search forward for matching fork
  769.     (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
  770.     )
  771.        ((match-end 4) ; endtable
  772.     ;; Search forward for matching table
  773.     (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" )
  774.     )
  775.        ((match-end 5) ; endspecify
  776.     ;; Search forward for matching specify
  777.     (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" )
  778.     )
  779.        ((match-end 6) ; endfunction
  780.     ;; Search forward for matching function
  781.     (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" )
  782.     )
  783.        ((match-end 7) ; endspecify
  784.     ;; Search forward for matching task
  785.     (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" )
  786.     )
  787.        )
  788.       (if (forward-word 1)
  789.       (catch 'skip
  790.         (let ((nest 1))
  791.           (while (verilog-re-search-forward reg nil 'move)
  792.         (cond 
  793.          ((match-end 2) ; end
  794.           (setq nest (1- nest))
  795.           (if (= 0 nest)
  796.               (throw 'skip 1)))
  797.          ((match-end 1) ; begin
  798.           (setq nest (1+ nest)))))
  799.           )
  800.         )
  801.     )
  802.       )
  803.      ((looking-at "\\(\\<\\(macro\\)?module\\>\\)\\|\\(\\<primitive\\>\\)")
  804.       (cond
  805.        ((match-end 1)
  806.     (verilog-re-search-forward "\\<endmodule\\>" nil 'move))
  807.        ((match-end 2)
  808.     (verilog-re-search-forward "\\<endprimitive\\>" nil 'move))
  809.        (t 
  810.     (goto-char st)
  811.     (if (= (following-char) ?\) )
  812.         (forward-char 1)
  813.       (forward-sexp 1)))))
  814.      (t
  815.       (goto-char st)
  816.       (if (= (following-char) ?\) )
  817.       (forward-char 1)
  818.     (forward-sexp 1)))
  819.      ) ;; cond
  820.     )
  821.   )
  822.  
  823.  
  824. (defun verilog-declaration-beg ()
  825.   (verilog-re-search-backward verilog-declaration-re (bobp) t))
  826.   
  827. (defsubst verilog-within-string ()
  828.   (save-excursion
  829.     (nth 3 (parse-partial-sexp (verilog-get-beg-of-line) (point)))))
  830.  
  831. (put 'verilog-mode 'font-lock-defaults 
  832.      '((verilog-font-lock-keywords-after-1930 )
  833.        nil ;; nil means highlight strings & comments as well as keywords
  834.        nil ;; nil means keywords must match case
  835.        nil ;; syntax table handled elsewhere
  836.        verilog-beg-of-defun ;; function to move to beginning of reasonable region to highlight
  837.        ))
  838.  
  839. ;;;###autoload
  840. (defun verilog-mode ()
  841. "Major mode for editing Verilog code. \\<verilog-mode-map>
  842. NEWLINE, TAB indents for Verilog code.  
  843. Delete converts tabs to spaces as it moves back.
  844. Supports highlighting.
  845.  
  846. Variables controlling indentation/edit style:
  847.  
  848.  verilog-indent-level           (default 3)
  849.     Indentation of Verilog statements with respect to containing block.
  850.  verilog-indent-level-module    (default 3)
  851.     Absolute indentation of Module level Verilog statements. 
  852.     Set to 0 to get initial and always statements lined up 
  853.     on the left side of your screen.
  854.  verilog-indent-level-declaration    (default 3)
  855.     Indentation of declarations with respect to containing block. 
  856.     Set to 0 to get them list right under containing block.
  857.  verilog-indent-level-behavorial    (default 3)
  858.     Indentation of first begin in a task or function block
  859.     Set to 0 to get such code to linedup underneath the task or function keyword
  860.  verilog-cexp-indent            (default 1)
  861.     Indentation of Verilog statements broken across lines.
  862.  verilog-case-indent            (default 2)
  863.     Indentation for case statements.
  864.  verilog-auto-newline           (default nil)
  865.     Non-nil means automatically newline after semicolons and the punctation 
  866.     mark after an end.
  867.  verilog-auto-indent-on-newline (default t)
  868.     Non-nil means automatically indent line after newline
  869.  verilog-tab-always-indent      (default t)
  870.     Non-nil means TAB in Verilog mode should always reindent the current line,
  871.     regardless of where in the line point is when the TAB command is used.
  872.  verilog-indent-begin-after-if  (default t)
  873.     Non-nil means to indent begin statements following a preceding
  874.     if, else, while, for and repeat statements, if any. otherwise,
  875.     the begin is lined up with the preceding token. If t, you get:
  876.       if (a)
  877.          begin
  878.     otherwise you get:
  879.       if (a)
  880.       begin
  881.  verilog-auto-endcomments       (default t)
  882.     Non-nil means a comment /* ... */ is set after the ends which ends 
  883.       cases, tasks, functions and modules.
  884.     The type and name of the object will be set between the braces.
  885.  verilog-minimum-comment-distance (default 40)
  886.     Minimum distance between begin and end required before a comment
  887.     will be inserted.  Setting this variable to zero results in every
  888.     end aquiring a comment; the default avoids too many redundanet
  889.     comments in tight quarters. 
  890.  verilog-auto-lineup            (default `(all))
  891.     List of contexts where auto lineup of :'s or ='s should be done.
  892.  
  893. Turning on Verilog mode calls the value of the variable verilog-mode-hook with
  894. no args, if that value is non-nil.
  895. Other useful functions are:
  896. \\[verilog-complete-word]\t-complete word with appropriate possibilities 
  897.    (functions, verilog keywords...)
  898. \\[verilog-comment-region]\t- Put marked area in a comment, fixing 
  899.    nested comments.
  900. \\[verilog-uncomment-region]\t- Uncomment an area commented with \
  901. \\[verilog-comment-region].
  902. \\[verilog-insert-block]\t- insert begin ... end;
  903. \\[verilog-star-comment]\t- insert /* ... */
  904. \\[verilog-mark-defun]\t- Mark function.
  905. \\[verilog-beg-of-defun]\t- Move to beginning of current function.
  906. \\[verilog-end-of-defun]\t- Move to end of current function.
  907. \\[verilog-label-be]\t- Label matching begin ... end, fork ... join 
  908.   and case ... endcase statements;
  909. "
  910.   (interactive)
  911.   (kill-all-local-variables)
  912.   (use-local-map verilog-mode-map)
  913.   (setq major-mode 'verilog-mode)
  914.   (setq mode-name "Verilog")
  915.   (setq local-abbrev-table verilog-mode-abbrev-table)
  916.   (set-syntax-table verilog-mode-syntax-table)
  917.   (make-local-variable 'indent-line-function)
  918.   (setq indent-line-function 'verilog-indent-line)
  919.   (setq comment-indent-function 'verilog-indent-comment)
  920.   (make-local-variable 'parse-sexp-ignore-comments)
  921.   (setq parse-sexp-ignore-comments nil)
  922.   (make-local-variable 'comment-start)
  923.   (make-local-variable 'comment-end)
  924.   (make-local-variable 'comment-multi-line)
  925.   (make-local-variable 'comment-start-skip)
  926.   (setq comment-start "// "
  927.     comment-end ""
  928.     comment-start-skip "/\\*+ *\\|// *"
  929.     comment-multi-line nil)
  930.   ;; Setting up things for font-lock 
  931.   (if (string-match "XEmacs" emacs-version) 
  932.       (progn 
  933.         (if (and (featurep 'menubar)
  934.          current-menubar 
  935.                  (not (assoc "Verilog" current-menubar))) 
  936.             (progn 
  937.               (set-buffer-menubar (copy-sequence current-menubar)) 
  938.               (add-submenu nil verilog-xemacs-menu))) ))
  939.   ;; Stuff for GNU emacs
  940.   (make-local-variable 'font-lock-defaults) 
  941.   (setq font-lock-defaults  
  942.     '((verilog-font-lock-keywords verilog-font-lock-keywords-1 
  943.                       verilog-font-lock-keywords-2 
  944.                       verilog-font-lock-keywords-3 
  945.                       verilog-font-lock-keywords-4) 
  946.       nil t)) 
  947.   ;; Tell imenu how to handle verilog. 
  948.   (make-local-variable 'imenu-generic-expression) 
  949.   (setq imenu-generic-expression verilog-imenu-generic-expression) 
  950.   ;; End GNU emacs stuff
  951.   (run-hooks 'verilog-mode-hook))
  952.  
  953.  
  954. ;;;
  955. ;;;  Electric functions
  956. ;;;
  957. (defun electric-verilog-terminate-line (&optional arg)
  958.   "Terminate line and indent next line."
  959.   (interactive)
  960.   ;; before that see if we are in a comment
  961.   (let ((state 
  962.      (save-excursion
  963.        (parse-partial-sexp (point-min) (point)))))
  964.     (cond
  965.      ((nth 7 state)            ; Inside // comment
  966.       (if (eolp)
  967.       (progn
  968.         (delete-horizontal-space)
  969.         (newline))
  970.     (progn 
  971.       (newline)
  972.       (insert-string "// ")
  973.       (beginning-of-line)
  974.       ))
  975.       (verilog-indent-line)
  976.       )
  977.      ((nth 4 state)            ; Inside any comment (hence /**/)
  978.       (newline)
  979.       (beginning-of-line)
  980.       (verilog-indent-comment t)
  981.       )
  982.      ((eolp)
  983.        ;; First, check if current line should be indented
  984.        (if (save-excursion 
  985.              (delete-horizontal-space)
  986.          (beginning-of-line)
  987.          (skip-chars-forward " \t")
  988.          (if (looking-at verilog-autoindent-lines-re)
  989.          (let ((indent-str (verilog-indent-line)))
  990.            ;; Maybe we should set some endcomments
  991.            (if verilog-auto-endcomments
  992.                (verilog-set-auto-endcomments indent-str arg))
  993.            (end-of-line)
  994.            (delete-horizontal-space)
  995.            (if arg
  996.                ()
  997.              (newline))
  998.            nil)
  999.            (progn
  1000.          (end-of-line)
  1001.          (delete-horizontal-space)
  1002.          't
  1003.          )))
  1004.        (newline)
  1005.      (forward-line 1)
  1006.      )
  1007.        ;; Indent next line
  1008.        (if verilog-auto-indent-on-newline
  1009.        (verilog-indent-line))
  1010.        )
  1011.      (t
  1012.       (newline)
  1013.       )
  1014.      )
  1015.     )
  1016.   )
  1017.   
  1018. (defun electric-verilog-semi ()
  1019.   "Insert `;' character and reindent the line."
  1020.   (interactive)
  1021.   (insert last-command-char)
  1022.   (if (verilog-in-comment-or-string-p)
  1023.       () 
  1024.     (save-excursion
  1025.       (beginning-of-line)
  1026.       (verilog-indent-line))
  1027.     (if (and verilog-auto-newline
  1028.          (= 0 (verilog-parenthesis-depth)))
  1029.     (electric-verilog-terminate-line))))
  1030.  
  1031. (defun electric-verilog-colon ()
  1032.   "Insert `:' and do all indentions except line indent on this line."
  1033.   (interactive)
  1034.   (insert last-command-char)
  1035.   ;; Do nothing if within string.
  1036.   (if (or
  1037.        (verilog-within-string)
  1038.        (not (verilog-in-case-region-p)))
  1039.       ()
  1040.     (save-excursion
  1041.       (let ((p (point))
  1042.         (lim (progn (verilog-beg-of-statement) (point))))
  1043.     (goto-char p)
  1044.     (verilog-backward-case-item lim)
  1045.     (verilog-indent-line)))
  1046. ;;    (let ((verilog-tab-always-indent nil))
  1047. ;;      (verilog-indent-line))
  1048.     )
  1049.   )
  1050.  
  1051. (defun electric-verilog-equal ()
  1052.   "Insert `=', and do indention if within block."
  1053.   (interactive)
  1054.   (insert last-command-char)
  1055. ;; Could auto line up expressions, but not yet
  1056. ;;  (if (eq (car (verilog-calculate-indent)) 'block)
  1057. ;;      (let ((verilog-tab-always-indent nil))
  1058. ;;    (verilog-indent-command)))
  1059. )
  1060.  
  1061.  
  1062. (defun electric-verilog-tick ()
  1063.   "Insert back-tick, and indent to coulmn 0 if this is a CPP directive."
  1064.   (interactive)
  1065.   (insert last-command-char)
  1066.   (if (save-excursion 
  1067.     (beginning-of-line) 
  1068.     (looking-at 
  1069. "^[ \t]*\`\\(\\<ifdef\\>\\|\\\<else\\>\\|\\<endif\\>\\|\\<define\\>\\)"))
  1070.       (save-excursion (beginning-of-line)
  1071.               (delete-horizontal-space))))
  1072.  
  1073. (defun electric-verilog-tab ()
  1074.   "Function called when TAB is pressed in Verilog mode."
  1075.   (interactive)
  1076.   ;; If verilog-tab-always-indent, indent the beginning of the line.
  1077.   (if verilog-tab-always-indent
  1078.       (let* (
  1079.          (boi-point 
  1080.           (save-excursion
  1081.         (beginning-of-line)
  1082.         (skip-chars-forward " \t")
  1083.         (let (type state )
  1084.           (setq type (verilog-indent-line))
  1085.           (setq state (car type))
  1086.           (cond
  1087.            ((eq state 'block)
  1088.             (if (looking-at verilog-behavorial-block-beg-re )
  1089.             (error 
  1090.              (concat 
  1091.               "The reserved word \""
  1092.               (buffer-substring (match-beginning 0) (match-end 0))
  1093.               "\" must be at the behavorial level!"))))
  1094.            ))
  1095.         (back-to-indentation)
  1096.         (point))))
  1097.         (if (< (point) boi-point)
  1098.             (back-to-indentation)))
  1099.     (progn (insert "\t"))
  1100.     )
  1101.   )
  1102.  
  1103.  
  1104.  
  1105. ;;;
  1106. ;;; Interactive functions
  1107. ;;;
  1108. (defun verilog-insert-block ()
  1109.   "Insert Verilog begin ... end; block in the code with right indentation."
  1110.   (interactive)
  1111.   (verilog-indent-line)
  1112.   (insert "begin")
  1113.   (electric-verilog-terminate-line)
  1114.   (save-excursion
  1115.     (electric-verilog-terminate-line)
  1116.     (insert "end")
  1117.     (beginning-of-line)
  1118.     (verilog-indent-line)))
  1119.  
  1120. (defun verilog-star-comment ()
  1121.   "Insert Verilog star comment at point."
  1122.   (interactive)
  1123.   (verilog-indent-line)
  1124.   (insert "/*")
  1125.   (save-excursion
  1126.     (newline)
  1127.     (insert " */"))
  1128.   (newline)
  1129.   (insert " * "))
  1130.  
  1131. (defun verilog-mark-defun ()
  1132.   "Mark the current verilog function (or procedure).
  1133. This puts the mark at the end, and point at the beginning."
  1134.   (interactive)
  1135.   (push-mark (point))
  1136.   (verilog-end-of-defun)
  1137.   (push-mark (point))
  1138.   (verilog-beg-of-defun)
  1139.   (if (fboundp 'zmacs-activate-region)
  1140.       (zmacs-activate-region)))
  1141.  
  1142. (defun verilog-comment-region (start end)
  1143.   "Put the region into a Verilog comment.
  1144. The comments that are in this area are \"deformed\":
  1145. `*)' becomes `!(*' and `}' becomes `!{'.
  1146. These deformed comments are returned to normal if you use
  1147. \\[verilog-uncomment-region] to undo the commenting.
  1148.  
  1149. The commented area starts with `verilog-exclude-str-start', and ends with
  1150. `verilog-include-str-end'.  But if you change these variables,
  1151. \\[verilog-uncomment-region] won't recognize the comments."
  1152.   (interactive "r")
  1153.   (save-excursion
  1154.     ;; Insert start and endcomments
  1155.     (goto-char end)
  1156.     (if (and (save-excursion (skip-chars-forward " \t") (eolp))
  1157.          (not (save-excursion (skip-chars-backward " \t") (bolp))))
  1158.     (forward-line 1)
  1159.       (beginning-of-line))
  1160.     (insert verilog-exclude-str-end)
  1161.     (setq end (point))
  1162.     (newline)
  1163.     (goto-char start)
  1164.     (beginning-of-line)
  1165.     (insert verilog-exclude-str-start)
  1166.     (newline)
  1167.     ;; Replace end-comments within commented area
  1168.     (goto-char end)
  1169.     (save-excursion
  1170.       (while (re-search-backward "\\*/" start t)
  1171.     (replace-match "*-/" t t)))
  1172.     (save-excursion
  1173.       (let ((s+1 (1+ start)))
  1174.     (while (re-search-backward "/\\*" s+1 t)
  1175.       (replace-match "/-*" t t))))
  1176.     )
  1177. )
  1178.  
  1179. (defun verilog-uncomment-region ()
  1180.   "Uncomment a commented area; change deformed comments back to normal.
  1181. This command does nothing if the pointer is not in a commented
  1182. area.  See also `verilog-comment-region'."
  1183.   (interactive)
  1184.   (save-excursion
  1185.     (let ((start (point))
  1186.       (end (point)))
  1187.       ;; Find the boundaries of the comment
  1188.       (save-excursion
  1189.     (setq start (progn (search-backward verilog-exclude-str-start nil t)
  1190.                (point)))
  1191.     (setq end (progn (search-forward verilog-exclude-str-end nil t)
  1192.              (point))))
  1193.       ;; Check if we're really inside a comment
  1194.       (if (or (equal start (point)) (<= end (point)))
  1195.       (message "Not standing within commented area.")
  1196.     (progn
  1197.       ;; Remove endcomment
  1198.       (goto-char end)
  1199.       (beginning-of-line)
  1200.       (let ((pos (point)))
  1201.         (end-of-line)
  1202.         (delete-region pos (1+ (point))))
  1203.       ;; Change comments back to normal
  1204.       (save-excursion
  1205.         (while (re-search-backward "\\*-/" start t)
  1206.           (replace-match "*/" t t)))
  1207.       (save-excursion
  1208.         (while (re-search-backward "/-\\*" start t)
  1209.           (replace-match "/*" t t)))
  1210.       ;; Remove startcomment
  1211.       (goto-char start)
  1212.       (beginning-of-line)
  1213.       (let ((pos (point)))
  1214.         (end-of-line)
  1215.         (delete-region pos (1+ (point)))))))))
  1216.  
  1217. (defun verilog-beg-of-defun ()
  1218.   "Move backward to the beginning of the current function or procedure."
  1219.   (interactive)
  1220.   (verilog-re-search-backward verilog-defun-re nil 'move)
  1221.   )
  1222. (defun verilog-end-of-defun ()
  1223.   (interactive)
  1224.   (verilog-re-search-forward verilog-end-defun-re nil 'move)
  1225.   )
  1226.  
  1227. (defun verilog-label-be (&optional arg)
  1228.   "Label matching begin ... end, fork ... join and case ... endcase
  1229.   statements in this module; With argument, first kill any existing
  1230.   labels."
  1231.   (interactive)
  1232.   (let ((cnt 0)
  1233.     (oldpos (point))
  1234.     (b (progn 
  1235.          (verilog-beg-of-defun) 
  1236.          (point-marker)))
  1237.     (e (progn 
  1238.          (verilog-end-of-defun) 
  1239.          (point-marker)))
  1240.     )
  1241.     (goto-char (marker-position b))
  1242.     (if (> (- e b) 200)
  1243.     (message  "Relabeling module..."))
  1244.     (while (and
  1245.         (> (marker-position e) (point))
  1246.         (verilog-re-search-forward 
  1247.          (concat 
  1248.           "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|"
  1249.           "\\(primitive\\)\\|\\(case\\)\\)?\\>"
  1250.           "\\|\\(`endif\\)\\|\\(`else\\)")
  1251.          nil 'move))
  1252.       (goto-char (match-beginning 0))
  1253.       (let ((indent-str (verilog-indent-line)))
  1254.     (verilog-set-auto-endcomments indent-str 't)
  1255.     (end-of-line)
  1256.     (delete-horizontal-space)
  1257.     )
  1258.       (setq cnt (1+ cnt))
  1259.       (if (= 9 (% cnt 10))
  1260.       (message "%d..." cnt))
  1261.       )
  1262.     (goto-char oldpos)
  1263.     (if (or
  1264.      (> (- e b) 200)
  1265.      (> cnt 20))
  1266.     (message  "%d lines autocommented" cnt))
  1267.     )
  1268.   )
  1269. (defun verilog-beg-of-statement ()
  1270.   "Move backward to beginning of statement"
  1271.   (interactive)
  1272.   (while (save-excursion 
  1273.        (and
  1274.         (not (looking-at verilog-complete-reg))
  1275.         (verilog-backward-syntactic-ws)
  1276.         (not (or (bolp) (= (preceding-char) ?\;)))
  1277.         )
  1278.        )
  1279.     (skip-chars-backward " \t")
  1280.     (verilog-backward-token))
  1281.   (let ((last (point)))
  1282.     (while (progn
  1283.          (setq last (point))
  1284.          (and (not (looking-at verilog-complete-reg))
  1285.           (verilog-continued-line))))
  1286.     (goto-char last)
  1287.     (verilog-forward-syntactic-ws)
  1288.     )
  1289.   )
  1290.  
  1291. (defun verilog-beg-of-statement-1 ()
  1292.   "Move backward to beginning of statement"
  1293.   (interactive)
  1294.   (let ((pt (point)))
  1295.     
  1296.     (while (and (not (looking-at verilog-complete-reg))
  1297.         (setq pt (point))
  1298.         (verilog-backward-token)
  1299.         (setq pt (point))
  1300.         (verilog-backward-syntactic-ws)
  1301.         (not (bolp))
  1302.         (not (= (preceding-char) ?\;)))
  1303.       )
  1304.     (goto-char pt)
  1305.     (while (progn
  1306.          (setq pt (point))
  1307.          (and (not (looking-at verilog-complete-reg))
  1308.           (not (= (preceding-char) ?\;))
  1309.           (verilog-continued-line))))
  1310.     (goto-char pt)
  1311.     (verilog-forward-syntactic-ws)
  1312.     )
  1313.   )
  1314. (defun verilog-end-of-statement ()
  1315.   "Move forward to end of current statement."
  1316.   (interactive)
  1317.   (let ((nest 0) pos)
  1318.     (or (looking-at verilog-beg-block-re)
  1319.     ;; Skip to end of statement
  1320.     (setq pos (catch 'found
  1321.             (while t
  1322.               (forward-sexp 1)
  1323.               (verilog-skip-forward-comment-or-string)
  1324.               (cond ((looking-at "[ \t]*;")
  1325.                  (skip-chars-forward "^;")
  1326.                  (forward-char 1)
  1327.                  (throw 'found (point)))
  1328.                 ((save-excursion
  1329.                    (forward-sexp -1)
  1330.                    (looking-at verilog-beg-block-re))
  1331.                  (goto-char (match-beginning 0))
  1332.                  (throw 'found nil))
  1333.                 ((eobp)
  1334.                  (throw 'found (point))))))))
  1335.     (if (not pos)
  1336.     ;; Skip a whole block
  1337.     (catch 'found
  1338.       (while t
  1339.         (verilog-re-search-forward verilog-end-statement-re nil 'move)
  1340.         (setq nest (if (match-end 1) 
  1341.                (1+ nest)
  1342.              (1- nest)))
  1343.         (cond ((eobp)
  1344.            (throw 'found (point)))
  1345.           ((= 0 nest)
  1346.            (throw 'found (verilog-end-of-statement))))))
  1347.       pos)))
  1348. (defun verilog-in-case-region-p ()
  1349.   "Return TRUE if in a case region: more specifically, point @ in the
  1350.   line foo : @ begin"
  1351.   (interactive)
  1352.   (save-excursion
  1353.     (if (and 
  1354.      (progn (verilog-forward-syntactic-ws)    
  1355.         (looking-at "\\<begin\\>"))
  1356.      (progn (verilog-backward-syntactic-ws)    
  1357.         (= (preceding-char) ?\:)))
  1358.     (catch 'found
  1359.       (let ((nest 1))
  1360.         (while t
  1361.           (verilog-re-search-backward 
  1362.            (concat "\\(\\<module\\>\\)\\|\\(\\<case[xz]?\\>[^:]\\)\\|"
  1363.                "\\(\\<endcase\\>\\)\\>")
  1364.            nil 'move)
  1365.           (cond
  1366.            ((match-end 3)
  1367.         (setq nest (1+ nest)))
  1368.            ((match-end 2)
  1369.         (if (= nest 1)
  1370.         (throw 'found 1))
  1371.         (setq nest (1- nest))
  1372.         )
  1373.            ( t
  1374.          (throw 'found (= nest 0)))
  1375.            )
  1376.           )
  1377.         )
  1378.       )
  1379.       nil)
  1380.     )
  1381.   )
  1382. (defun verilog-backward-case-item (lim)
  1383.   "Skip backward to nearest enclosing case item"
  1384.   (interactive)
  1385.   (let (
  1386.     (str 'nil)
  1387.     (lim1 
  1388.      (progn 
  1389.        (save-excursion 
  1390.          (verilog-re-search-backward verilog-endcomment-reason-re 
  1391.                      lim 'move)
  1392.          (point)))))
  1393.     ;; Try to find the real :
  1394.     (if (save-excursion (search-backward ":" lim1 t))
  1395.     (let ((colon 0)
  1396.           b e )
  1397.       (while 
  1398.           (and 
  1399.            (< colon 1)
  1400.            (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)" 
  1401.                        lim1 'move))
  1402.         (cond 
  1403.          ((match-end 1) ;; [
  1404.           (setq colon (1+ colon))
  1405.           (if (>= colon 0)
  1406.           (error "unbalanced [")))
  1407.          ((match-end 2) ;; ]
  1408.           (setq colon (1- colon)))
  1409.          
  1410.          ((match-end 3) ;; :
  1411.           (setq colon (1+ colon)))
  1412.          
  1413.          )
  1414.         )
  1415.       ;; Skip back to begining of case item
  1416.       (skip-chars-backward "\t ")
  1417.       (verilog-skip-backward-comment-or-string)
  1418.       (setq e (point))
  1419.       (setq b 
  1420.         (progn
  1421.           (if 
  1422.               (verilog-re-search-backward 
  1423.                "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
  1424.               (progn
  1425.             (cond 
  1426.              ((match-end 1)
  1427.               (goto-char (match-end 1))
  1428.               (verilog-forward-ws&directives)
  1429.               (if (looking-at "(")
  1430.                   (progn
  1431.                 (forward-sexp)
  1432.                 (verilog-forward-ws&directives)
  1433.                 ))
  1434.               (point))
  1435.              (t
  1436.               (goto-char (match-end 0))
  1437.               (verilog-forward-ws&directives)
  1438.               (point))
  1439.              ))
  1440.             (error "Malformed case item")
  1441.             )
  1442.           )
  1443.         )
  1444.       (setq str (buffer-substring b e))
  1445.       (if 
  1446.           (setq e 
  1447.             (string-match 
  1448.              "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
  1449.           (setq str (concat (substring str 0 e) "...")))
  1450.       str)
  1451.       'nil)
  1452.     )
  1453.   )
  1454.  
  1455.  
  1456. ;;;
  1457. ;;; Other functions
  1458. ;;;
  1459.  
  1460. (defun kill-existing-comment ()
  1461.   "kill autocomment on this line"
  1462.   (save-excursion 
  1463.     (let* (
  1464.        (e (progn
  1465.         (end-of-line)
  1466.         (point)))
  1467.        (b (progn 
  1468.         (beginning-of-line)
  1469.         (search-forward "//" e t))))
  1470.       (if b
  1471.       (delete-region (- b 2) e))
  1472.       )
  1473.     )
  1474.   )
  1475.  
  1476. (defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
  1477.   "Insert `// case: 7 ' or `// NAME ' on this line if appropriate.
  1478. Insert `// case expr ' if this line ends a case block.  
  1479. Insert `// ifdef FOO ' if this line ends code conditional on FOO.
  1480. Insert `// NAME ' if this line ends a module or primitive named NAME."
  1481.   (save-excursion
  1482.     (cond 
  1483.      (; Comment close preprocessor directives
  1484.       (and 
  1485.        (looking-at "\\(`endif\\)\\|\\(`else\\)")
  1486.        (or  kill-existing-comment    
  1487.         (not (save-excursion
  1488.            (end-of-line)
  1489.            (search-backward "//" (verilog-get-beg-of-line) t)))))
  1490.       (let ( (reg "\\(`else\\)\\|\\(`ifdef\\)\\|\\(`endif\\)")
  1491.          (nest 1)
  1492.          b e 
  1493.          (else (if (match-end 2)
  1494.                1
  1495.              0))
  1496.          )
  1497.     (end-of-line)
  1498.     (if kill-existing-comment
  1499.         (kill-existing-comment))
  1500.     (delete-horizontal-space)
  1501.     (save-excursion
  1502.       (backward-sexp 1)
  1503.       (while (and (/= nest 0)
  1504.               (verilog-re-search-backward reg nil 'move))
  1505.         (cond 
  1506.          ((match-end 1) ; `else
  1507.           (if (= nest 1)
  1508.           (setq else 1)))
  1509.          ((match-end 2) ; `ifdef
  1510.           (setq nest (1- nest)))
  1511.          ((match-end 3) ; `endif
  1512.           (setq nest (1+ nest)))
  1513.          ))
  1514.       (if (match-end 0)
  1515.           (setq b (progn 
  1516.             (skip-chars-forward "^ \t")
  1517.             (verilog-forward-syntactic-ws)
  1518.             (point))
  1519.             e (progn
  1520.             (skip-chars-forward "a-zA-Z0-9_")
  1521.             (point)
  1522.             ))))
  1523.     (if b
  1524.         (if (> (- (point) b) verilog-minimum-comment-distance)
  1525.         (insert (concat (if 
  1526.                     (= else 0)
  1527.                     " // ifdef " 
  1528.                   " // !ifdef ")
  1529.                 (buffer-substring b e))))
  1530.       (progn
  1531.         (insert " // unmatched `endif")
  1532.         (ding 't))
  1533.       )))
  1534.      
  1535.      (; Comment close case/function/task/module and named block
  1536.       (and (looking-at "\\<end")
  1537.        (or kill-existing-comment
  1538.            (not (save-excursion
  1539.               (end-of-line)
  1540.               (search-backward "//" (verilog-get-beg-of-line) t)))))
  1541.       (let ((type (car indent-str)))
  1542.     (if (eq type 'declaration)
  1543.         ()
  1544.       (if 
  1545.           (looking-at verilog-enders-re)
  1546.           (cond
  1547.            (;- This is a case block; search back for the start of this case
  1548.         (match-end 1)
  1549.         
  1550.         (let ((err 't)
  1551.               (str "UNMATCHED!!"))
  1552.           (save-excursion
  1553.             (verilog-leap-to-head)
  1554.             (if (match-end 0)
  1555.             (progn
  1556.               (goto-char (match-end 1))
  1557.               (setq str (concat (buffer-substring (match-beginning 1) (match-end 1))
  1558.                         (verilog-get-expr)))
  1559.               (setq err nil))))
  1560.           (end-of-line)
  1561.           (if kill-existing-comment
  1562.               (kill-existing-comment))
  1563.           (delete-horizontal-space)
  1564.           (insert (concat " // " str ))
  1565.           (if err (ding 't))
  1566.           ))
  1567.            
  1568.            (;- This is a begin..end block
  1569.         (match-end 2)
  1570.         (let ((str " // UNMATCHED !!")
  1571.               (err 't)
  1572.               (here (point))
  1573.               there
  1574.               cntx
  1575.               )
  1576.           (save-excursion
  1577.             (verilog-leap-to-head)
  1578.             (setq there (point))
  1579.             (if (not (match-end 0))
  1580.             (progn
  1581.               (goto-char here)
  1582.               (end-of-line)
  1583.               (if kill-existing-comment
  1584.                   (kill-existing-comment))
  1585.               (delete-horizontal-space)
  1586.               (insert str)
  1587.               (ding 't)              
  1588.               )
  1589.               (let ( sp 
  1590.                 (lim (save-excursion (verilog-beg-of-defun) (point)))
  1591.                 (here (point))
  1592.                 )
  1593.             (cond
  1594.              (;-- handle named block differently
  1595.               (looking-at verilog-named-block-re)
  1596.               (search-forward ":")
  1597.               (setq there (point))
  1598.               (setq str (verilog-get-expr))
  1599.               (setq err nil)
  1600.               (setq str (concat " // block: " str )))
  1601.              
  1602.              ((verilog-in-case-region-p) ;-- handle case item differently
  1603.               (goto-char here)
  1604.               (setq str (verilog-backward-case-item lim))
  1605.               (setq there (point))
  1606.               (setq err nil)
  1607.               (setq str (concat " // case: " str ))
  1608.               )
  1609.              (;- try to find "reason" for this begin
  1610.               (cond 
  1611.                (;
  1612.                 (eq here (progn 
  1613.                        (verilog-backward-token)
  1614.                        (verilog-beg-of-statement) 
  1615.                        (point)))
  1616.                 (setq err nil)
  1617.                 (setq str ""))
  1618.                ((looking-at verilog-endcomment-reason-re)
  1619.                 (setq there (match-end 0))
  1620.                 (setq cntx (concat 
  1621.                     (buffer-substring (match-beginning 0) (match-end 0)) " "))
  1622.                 (cond
  1623.                  (;
  1624.                   (match-end 2)
  1625.                   (setq err nil)
  1626.                   (save-excursion
  1627.                 (goto-char sp)
  1628.                 (if (and (verilog-continued-line)
  1629.                      (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>"))
  1630.                     (progn
  1631.                       (goto-char (match-end 0))
  1632.                       (setq there (point))
  1633.                       (setq str 
  1634.                         (concat " // "
  1635.                             (buffer-substring (match-beginning 0) (match-end 0)) " "
  1636.                             (verilog-get-expr))))
  1637.                   (setq str "")          
  1638.                   )
  1639.                 )
  1640.                   )
  1641.                  (;- else 
  1642.                   (match-end 4)
  1643.                   (let ((nest 0)
  1644.                     ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)")
  1645.                     )
  1646.                 (catch 'skip
  1647.                   (while (verilog-re-search-backward reg nil 'move)
  1648.                     (cond 
  1649.                      ((match-end 1) ; begin
  1650.                       (setq nest (1- nest)))
  1651.                      ((match-end 2)                       ; end
  1652.                       (setq nest (1+ nest)))
  1653.                      ((match-end 3)
  1654.                       (if (= 0 nest)
  1655.                       (progn
  1656.                         (goto-char (match-end 0))
  1657.                         (setq there (point))
  1658.                         (setq err nil)
  1659.                         (setq str (verilog-get-expr))
  1660.                         (setq str (concat " // else: !if" str ))
  1661.                         (throw 'skip 1))
  1662.                     )))
  1663.                     )
  1664.                   )
  1665.                 )
  1666.                   )
  1667.                  (;- end else 
  1668.                   (match-end 5)
  1669.                   (goto-char there)
  1670.                   (let ((nest 0)
  1671.                     ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)")
  1672.                     )
  1673.                 (catch 'skip
  1674.                   (while (verilog-re-search-backward reg nil 'move)
  1675.                     (cond 
  1676.                      ((match-end 1) ; begin
  1677.                       (setq nest (1- nest)))
  1678.                      ((match-end 2)                       ; end
  1679.                       (setq nest (1+ nest)))
  1680.                      ((match-end 3)
  1681.                       (if (= 0 nest)
  1682.                       (progn
  1683.                         (goto-char (match-end 0))
  1684.                         (setq there (point))
  1685.                         (setq err nil)
  1686.                         (setq str (verilog-get-expr))
  1687.                         (setq str (concat " // else: !if" str ))
  1688.                         (throw 'skip 1))
  1689.                     )))
  1690.                     )
  1691.                   )
  1692.                 )
  1693.                   )
  1694.  
  1695.                  (;- task/function/initial et cetera
  1696.                   t
  1697.                   (match-end 0)
  1698.                   (goto-char (match-end 0))
  1699.                   (setq there (point))
  1700.                   (setq err nil)
  1701.                   (setq str (verilog-get-expr))
  1702.                   (setq str (concat " // " cntx str )))
  1703.                  
  1704.                  (;-- otherwise...
  1705.                   (setq str " // auto-endcomment confused ")
  1706.                   )
  1707.                  )
  1708.                 )
  1709.                ((and
  1710.                  (verilog-in-case-region-p) ;-- handle case item differently
  1711.                  (progn
  1712.                    (setq there (point))                   
  1713.                    (goto-char here)
  1714.                    (setq str (verilog-backward-case-item lim))))
  1715.                 (setq err nil)
  1716.                 (setq str (concat " // case: " str ))
  1717.                 )
  1718.                )
  1719.               )
  1720.              )
  1721.             )
  1722.               (goto-char here)
  1723.               (end-of-line)
  1724.               (if kill-existing-comment
  1725.               (kill-existing-comment))
  1726.               (delete-horizontal-space)
  1727.               (if (or err
  1728.                   (> (- here there) verilog-minimum-comment-distance))
  1729.               (insert str))
  1730.               (if err (ding 't))
  1731.               )
  1732.             )
  1733.           )
  1734.         )
  1735.  
  1736.  
  1737.            (;- this is end{function,task,module}
  1738.         t 
  1739.         (let (string reg (width nil))
  1740.           (end-of-line)
  1741.           (if kill-existing-comment
  1742.               (kill-existing-comment))
  1743.           (delete-horizontal-space)
  1744.           (backward-sexp)
  1745.           (cond 
  1746.            ((match-end 5) 
  1747.             (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
  1748.             (setq width "\\([ \t]*\\[[^]]*\\]\\)?")
  1749.             )
  1750.            ((match-end 6) 
  1751.             (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)"))
  1752.            ((match-end 7) 
  1753.             (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
  1754.            ((match-end 8) 
  1755.             (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|function\\|task\\|\\(macro\\)?module\\)\\>\\)"))
  1756.            )
  1757.           (let (b e)
  1758.             (save-excursion
  1759.               (verilog-re-search-backward reg nil 'move)
  1760.               (cond 
  1761.                ((match-end 1)
  1762.             (setq b (progn 
  1763.                   (skip-chars-forward "^ \t")
  1764.                   (verilog-forward-ws&directives)
  1765.                   (if (and width (looking-at width))
  1766.                       (progn
  1767.                     (goto-char (match-end 0))
  1768.                     (verilog-forward-ws&directives)
  1769.                     ))
  1770.                   (point))
  1771.                   e (progn 
  1772.                   (skip-chars-forward "a-zA-Z0-9_")
  1773.                   (point)))
  1774.             (setq string (buffer-substring b e)))
  1775.                (t
  1776.             (ding 't)
  1777.             (setq string "unmactched end(function|task|module|primitive)")))))
  1778.           (end-of-line)
  1779.           (insert (concat " // " string )))
  1780.         )
  1781.            )
  1782.         )
  1783.       )
  1784.     )
  1785.       )
  1786.      )
  1787.     )
  1788.   )
  1789.  
  1790. (defun verilog-get-expr()
  1791.   "Grab expression at point, e.g, case ( a | b & (c ^d))"
  1792.   (let* ((b (progn 
  1793.           (verilog-forward-syntactic-ws)
  1794.           (skip-chars-forward " \t")
  1795.           (point)))
  1796.      (e (let ((par 1)) 
  1797.           (cond
  1798.            ((looking-at "(")
  1799.         (forward-char 1)
  1800.         (while (and (/= par 0) 
  1801.                 (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
  1802.           (cond
  1803.            ((match-end 1)
  1804.             (setq par (1+ par)))
  1805.            ((match-end 2)
  1806.             (setq par (1- par)))))
  1807.         (point))
  1808.            ((looking-at "\\[")
  1809.         (forward-char 1)
  1810.         (while (and (/= par 0) 
  1811.                 (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move))
  1812.           (cond
  1813.            ((match-end 1)
  1814.             (setq par (1+ par)))
  1815.            ((match-end 2)
  1816.             (setq par (1- par)))))
  1817.         (verilog-forward-syntactic-ws)
  1818.         (skip-chars-forward "^ \t\n")        
  1819.         (point))
  1820.            ((looking-at "/[/\\*]")
  1821.         b)
  1822.            ('t
  1823.         (skip-chars-forward "^: \t\n")
  1824.         (point)
  1825.         ))))
  1826.      (str (buffer-substring b e)))
  1827.     (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
  1828.     (setq str (concat (substring str 0 e) "...")))
  1829.     str)
  1830.   )
  1831.  
  1832.  
  1833. ;;;
  1834. ;;; Indentation
  1835. ;;;
  1836. (defconst verilog-indent-alist
  1837.   '((block       . (+ ind verilog-indent-level))
  1838.     (case        . (+ ind verilog-case-indent))
  1839.     (cparenexp   . (+ ind verilog-indent-level))
  1840.     (cexp        . (+ ind verilog-indent-level))
  1841.     (defun       . verilog-indent-level-module)
  1842.     (declaration . verilog-indent-level-declaration)
  1843.     (tf          . verilog-indent-level)
  1844.     (behavorial  . (+ verilog-indent-level-behavorial verilog-indent-level-module))
  1845.     (statement   . ind)
  1846.     (cpp         . 0)
  1847.     (comment     . (verilog-indent-comment))
  1848.     (unknown     . 3) 
  1849.     (string      . 0)))
  1850.  
  1851. (defun verilog-calculate-indent ()
  1852.   "Calculate the indent of the current Verilog line, through examination
  1853. of previous lines.  Once a line is found that is definitive as to the
  1854. type of the current line, return that lines' indent level and it's
  1855. type. Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
  1856.   (save-excursion
  1857.     (let* ((starting_position (point))
  1858.        (par 0) 
  1859.        (begin (looking-at "[ \t]*begin\\>"))
  1860.        (type (catch 'nesting
  1861.            ;; Keep working backwards until we can figure out
  1862.            ;; what type of statement this is.
  1863.            ;; Basically we need to figure out 
  1864.            ;; 1) if this is a continuation of the previous line;
  1865.            ;; 2) are we in a block scope (begin..end)
  1866.            
  1867.            ;; if we are in a comment, done.
  1868.            (if (verilog-in-star-comment-p)   (throw 'nesting 'comment))
  1869.  
  1870.            ;; if we are in a parenthesized list, done.
  1871.            (if (verilog-in-paren) (progn (setq par 1) (throw 'nesting 'block)))
  1872.  
  1873.            ;; See if we are continuing a previous line
  1874.            (while t
  1875.              ;; trap out if we crawl off the top of the buffer
  1876.              (if (bobp) (throw 'nesting 'cpp))
  1877.  
  1878.              (if (verilog-continued-line-1)
  1879.              (let ((sp (point)))
  1880.                (if (and
  1881.                 (not (looking-at verilog-complete-reg))
  1882.                 (verilog-continued-line-1))
  1883.                    (progn (goto-char sp)
  1884.                       (throw 'nesting 'cexp))
  1885.                  (goto-char sp))
  1886.                
  1887.                (if (and begin
  1888.                     (not verilog-indent-begin-after-if)
  1889.                     (looking-at verilog-no-indent-begin-re))
  1890.                    (throw 'nesting 'statement)
  1891.                  (progn
  1892.                    (throw 'nesting 'cexp)
  1893.                    )
  1894.                  ))
  1895.  
  1896.                ;; not a continued line
  1897.                (goto-char starting_position))
  1898.  
  1899.              (if (looking-at "\\<else\\>")
  1900.              ;; search back for governing if, striding across begin..end pairs
  1901.              ;; appropriately
  1902.              (let ((elsec 1))
  1903.                (while (verilog-re-search-backward verilog-ends-re nil 'move)
  1904.                  (cond 
  1905.                   ((match-end 1) ; else, we're in deep
  1906.                    (setq elsec (1+ elsec))                 
  1907.                    )
  1908.                   ((match-end 2) ; found it
  1909.                    (setq elsec (1- elsec))
  1910.                    (if (= 0 elsec)
  1911.                    ;; Now previous line describes syntax
  1912.                    (throw 'nesting 'statement)
  1913.                    ))
  1914.                   (t ; endblock
  1915.                 ; try to leap back to matching outward block by striding across
  1916.                 ; indent level changing tokens then immediately
  1917.                 ; previous line governs indentation.
  1918.                    (let ((reg)(nest 1))
  1919. ;;                 (looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify
  1920.                  (cond 
  1921.                   ((match-end 3) ; end
  1922.                    ;; Search back for matching begin
  1923.                    (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" )
  1924.                    )
  1925.                   ((match-end 4) ; endcase
  1926.                    ;; Search back for matching case
  1927.                    (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
  1928.                    )
  1929.                   ((match-end 5) ; join
  1930.                    ;; Search back for matching fork
  1931.                    (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
  1932.                    )
  1933.                   ((match-end 6) ; endtable
  1934.                    ;; Search back for matching table
  1935.                    (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" )
  1936.                    )
  1937.                   ((match-end 7) ; endspecify
  1938.                    ;; Search back for matching specify
  1939.                    (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" )
  1940.                    )
  1941.                   ((match-end 8) ; endfunction
  1942.                    ;; Search back for matching function
  1943.                    (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" )
  1944.                    )
  1945.                   ((match-end 9) ; endtask
  1946.                    ;; Search back for matching task
  1947.                    (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" )
  1948.                    )
  1949.                   )
  1950.                  (catch 'skip
  1951.                    (while (verilog-re-search-backward reg nil 'move)
  1952.                      (cond 
  1953.                       ((match-end 1) ; begin
  1954.                        (setq nest (1- nest))
  1955.                        (if (= 0 nest)
  1956.                        (throw 'skip 1)))
  1957.                       ((match-end 2) ; end
  1958.                        (setq nest (1+ nest)))))
  1959.                    )
  1960.                  )
  1961.                    )
  1962.                   )
  1963.                  )
  1964.                )
  1965.                )
  1966.              (throw 'nesting (verilog-calc-1))
  1967.              )
  1968.            )
  1969.          )
  1970.        )
  1971.       ;; Return type of block and indent level.
  1972.       (if (not type)
  1973.       (setq type 'cpp))
  1974.       (if (> par 0)            ; Unclosed Parenthesis 
  1975.       (list 'cparenexp par)
  1976.     (cond
  1977.       ((eq type 'case)
  1978.        (list type (verilog-case-indent-level)))
  1979.       ((eq type 'statement)
  1980.        (list type (current-column)))
  1981.       ((eq type 'defun)
  1982.        (list type 0))
  1983.       (t
  1984.        (list type (verilog-indent-level)))))
  1985.       )
  1986.     )
  1987.   )
  1988. (defun verilog-calc-1 ()
  1989.   ""
  1990.   (catch 'nesting
  1991.     (while (verilog-re-search-backward verilog-indent-re nil 'move)
  1992.       (cond 
  1993.        ((looking-at verilog-beg-block-re-1)
  1994.     (cond
  1995.      ((match-end 2)  (throw 'nesting 'case))
  1996.      (t              (throw 'nesting 'block))))
  1997.  
  1998.        ((looking-at verilog-end-block-re)
  1999.     (verilog-leap-to-head)
  2000.     (if (verilog-in-case-region-p)
  2001.         (progn
  2002.           (verilog-leap-to-case-head)
  2003.           (if (looking-at verilog-case-re)
  2004.           (throw 'nesting 'case))
  2005.           )))
  2006.             
  2007.        ((looking-at verilog-defun-level-re)
  2008.     (throw 'nesting 'defun)) 
  2009.  
  2010.        ((looking-at verilog-cpp-level-re)
  2011.     (throw 'nesting 'cpp))
  2012.  
  2013.        ((looking-at verilog-behavorial-level-re)
  2014.     (throw 'nesting 'behavorial))
  2015.             
  2016.        ((bobp) 
  2017.     (throw 'nesting 'cpp))
  2018.        )
  2019.       )
  2020.     )
  2021.   )
  2022.  
  2023. (defun verilog-leap-to-case-head () ""
  2024.   (let ((nest 1))
  2025.     (while (/= 0 nest)
  2026.       (verilog-re-search-backward "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" nil 'move)
  2027.       (cond 
  2028.        ((match-end 1)
  2029.     (setq nest (1- nest)))
  2030.        ((match-end 2)
  2031.     (setq nest (1+ nest)))
  2032.        ((bobp)
  2033.     (ding 't)
  2034.     (setq nest 0))
  2035.        )
  2036.       )
  2037.     )
  2038.   )
  2039.  
  2040. (defun verilog-leap-to-head () 
  2041.   "Move point to the head of this block; jump from end to matching begin,
  2042.    from endcase to matching case, and so on."
  2043.   (let (reg 
  2044.     snest
  2045.     (nest 1))
  2046.     (cond 
  2047.      ((looking-at "\\<end\\>")
  2048.       ;; Search back for matching begin
  2049.       (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|" 
  2050.             "\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)" )))
  2051.      
  2052.      ((looking-at "\\<endcase\\>")
  2053.       ;; Search back for matching case
  2054.       (setq reg "\\(\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)" )
  2055.       )
  2056.      ((looking-at "\\<join\\>")
  2057.       ;; Search back for matching fork
  2058.       (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
  2059.       )
  2060.      ((looking-at "\\<endtable\\>")
  2061.       ;; Search back for matching table
  2062.       (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" )
  2063.       )
  2064.      ((looking-at "\\<endspecify\\>")
  2065.       ;; Search back for matching specify
  2066.       (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" )
  2067.       )
  2068.      ((looking-at "\\<endfunction\\>")
  2069.       ;; Search back for matching function
  2070.       (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" )
  2071.       )
  2072.      ((looking-at "\\<endtask\\>")
  2073.       ;; Search back for matching task
  2074.       (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" )
  2075.       )
  2076.      )
  2077.     (catch 'skip
  2078.       (let (sreg)
  2079.     (while (verilog-re-search-backward reg nil 'move)
  2080.       (cond 
  2081.        ((match-end 1) ; begin
  2082.         (setq nest (1- nest))
  2083.         (if (= 0 nest)
  2084.         ;; Now previous line describes syntax
  2085.         (throw 'skip 1))
  2086.         (if (and snest
  2087.              (= snest nest))
  2088.         (setq reg sreg))
  2089.         )
  2090.        ((match-end 2) ; end
  2091.         (setq nest (1+ nest))
  2092.         )
  2093.        ((match-end 3)
  2094.         ;; endcase, jump to case
  2095.         (setq snest nest)
  2096.         (setq nest (1+ nest))
  2097.         (setq sreg reg)
  2098.         (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
  2099.         )
  2100.        ((match-end 4)
  2101.         ;; join, jump to fork
  2102.         (setq snest nest)
  2103.         (setq nest (1+ nest))
  2104.         (setq sreg reg)
  2105.         (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
  2106.         )
  2107.        )
  2108.       )
  2109.     )
  2110.       )
  2111.     )
  2112.   )
  2113.  
  2114. (defun verilog-continued-line-1 ()
  2115.   "Return true if this is a continued line.
  2116.    Set point to where line starts"
  2117.   (let ((continued 't))
  2118.     (if (eq 0 (forward-line -1))
  2119.     (progn
  2120.       (end-of-line)
  2121.       (verilog-backward-ws&directives)
  2122.       (if (bobp)
  2123.           (setq continued nil)
  2124.         (setq continued (verilog-backward-token))
  2125.         )
  2126.       )
  2127.       (setq continued nil)
  2128.       )
  2129.     continued)
  2130.   )
  2131.  
  2132. (defun verilog-continued-line ()
  2133.   "Return true if this is a continued line.
  2134.    Set point to where line starts"
  2135.   (let ((continued 't))
  2136.     (if (eq 0 (forward-line -1))
  2137.     (progn
  2138.       (end-of-line)
  2139.       (verilog-backward-ws&directives)
  2140.       (if (bobp)
  2141.           (setq continued nil)
  2142.         (while (and continued
  2143.             (save-excursion
  2144.               (skip-chars-backward " \t") 
  2145.               (not (bolp))))
  2146.         (setq continued (verilog-backward-token))
  2147.           ) ;; while
  2148.         )
  2149.       )
  2150.       (setq continued nil)
  2151.       )
  2152.     continued)
  2153.   )
  2154.  
  2155. (defun verilog-backward-token ()
  2156.   "step backward token, returning true if we are now at an end of line token"
  2157.   (verilog-backward-syntactic-ws)
  2158.   (cond 
  2159.    ((bolp)
  2160.     nil)
  2161.    (;-- Anything ending in a ; is complete
  2162.     (= (preceding-char) ?\;)
  2163.     nil)
  2164.    (;-- Could be 'case (foo)' or 'always @(bar)' which is complete
  2165.     (= (preceding-char) ?\))
  2166.     (progn
  2167.       (backward-char)
  2168.       (backward-up-list 1)
  2169.       (verilog-backward-syntactic-ws)
  2170.       (forward-word -1)
  2171.       (not (looking-at "\\<case[xz]?\\>[^:]"))))
  2172.    (;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
  2173.     t
  2174.     (forward-word -1)
  2175.     (cond 
  2176.      ( 
  2177.       (looking-at "\\(else\\)\\|\\(initial\\>\\)\\|\\(always\\>\\)")  
  2178.       t)
  2179.      ( 
  2180.       (looking-at verilog-indent-reg) 
  2181.       nil)
  2182.      (t
  2183.       (let 
  2184.       ((back (point)))
  2185.     (verilog-backward-syntactic-ws)
  2186.     (cond
  2187.      ((= (preceding-char) ?\:)
  2188.       (backward-char)
  2189.       (verilog-backward-syntactic-ws)
  2190.       (backward-sexp)
  2191.       (if (looking-at "begin")
  2192.           nil
  2193.         t)
  2194.       )
  2195.      ((= (preceding-char) ?\#)
  2196.       (backward-char)
  2197.       t)
  2198.      ((= (preceding-char) ?\`)
  2199.       (backward-char)
  2200.       t)
  2201.      
  2202.      (t
  2203.       (goto-char back)
  2204.       t)
  2205.      )
  2206.     )
  2207.       )
  2208.      )
  2209.     )
  2210.    )
  2211. )
  2212.  
  2213. (defun verilog-backward-syntactic-ws (&optional lim)
  2214.   ;; Backward skip over syntactic whitespace for Emacs 19.
  2215.   (save-restriction
  2216.     (let* ((lim (or lim (point-min)))
  2217.        (here lim)
  2218.        bol
  2219.        )
  2220.       (if (< lim (point))
  2221.       (progn
  2222.         (narrow-to-region lim (point))
  2223.         (while (/= here (point))
  2224.           (setq here (point))
  2225.           (forward-comment (-(buffer-size)))
  2226.           (save-excursion
  2227.         (setq bol (progn (beginning-of-line) (point))))
  2228.           (search-backward "//" bol t)
  2229.           )))
  2230.       ))
  2231.   t)
  2232.  
  2233. (defun verilog-forward-syntactic-ws (&optional lim)
  2234.   ;; forward skip over syntactic whitespace for Emacs 19.
  2235.   (save-restriction
  2236.     (let* ((lim (or lim (point-max)))
  2237.        (here lim)
  2238.        )
  2239.       (if (> lim (point))
  2240.       (progn
  2241.         (narrow-to-region (point) lim)
  2242.         (while (/= here (point))
  2243.           (setq here (point))
  2244.           (forward-comment (buffer-size))
  2245.           )))
  2246.       )))
  2247.  
  2248. (defun verilog-backward-ws&directives (&optional lim)
  2249.   ;; Backward skip over syntactic whitespace and compiler directives for Emacs 19.
  2250.   (save-restriction
  2251.     (let* ((lim (or lim (point-min)))
  2252.        (here lim)
  2253.        jump
  2254.        )
  2255.       (if (< lim (point))
  2256.       (progn
  2257.         (let ((state 
  2258.            (save-excursion
  2259.              (parse-partial-sexp (point-min) (point)))))
  2260.           (cond
  2261.            ((nth 4 state) ;; in /* */ comment
  2262.         (verilog-re-search-backward "/\*" nil 'move)
  2263.         )
  2264.            ((nth 7 state) ;; in // comment
  2265.         (verilog-re-search-backward "//" nil 'move)
  2266.         )))
  2267.         (narrow-to-region lim (point))
  2268.         (while (/= here (point))
  2269.           (setq here (point))
  2270.           (forward-comment (-(buffer-size)))
  2271.           (save-excursion
  2272.         (beginning-of-line)
  2273.         (if (looking-at "[ \t]*\\(`define\\)\\|\\(`ifdef\\)\\|\\(`else\\)\\|\\(`endif\\)\\|\\(`timescale\\)\\|\\(`include\\)")
  2274.             (setq jump t)
  2275.           (setq jump nil)))
  2276.           (if jump
  2277.           (beginning-of-line))
  2278.           )))
  2279.       )))
  2280.  
  2281. (defun verilog-forward-ws&directives (&optional lim)
  2282.   ;; forward skip over syntactic whitespace and compiler directives for Emacs 19.
  2283.   (save-restriction
  2284.     (let* ((lim (or lim (point-max)))
  2285.        (here lim)
  2286.        jump
  2287.        )
  2288.       (if (> lim (point))
  2289.       (progn
  2290.         (let ((state 
  2291.            (save-excursion
  2292.              (parse-partial-sexp (point-min) (point)))))
  2293.           (cond
  2294.            ((nth 4 state) ;; in /* */ comment
  2295.         (verilog-re-search-forward "/\*" nil 'move)
  2296.         )
  2297.            ((nth 7 state) ;; in // comment
  2298.         (verilog-re-search-forward "//" nil 'move)
  2299.         )))
  2300.         (narrow-to-region (point) lim)
  2301.         (while (/= here (point))
  2302.           (setq here (point))
  2303.           (forward-comment (buffer-size))
  2304.           (save-excursion
  2305.         (beginning-of-line)
  2306.         (if (looking-at "[ \t]*\\(`define\\)\\|\\(`ifdef\\)\\|\\(`else\\)\\|\\(`endif\\)\\|\\(`timescale\\)")
  2307.             (setq jump t)))
  2308.           (if jump
  2309.           (beginning-of-line 2))
  2310.           )))
  2311.       )))
  2312. (defun verilog-parenthesis-depth ()
  2313.  "Return non zero if in parenthetical-expression"
  2314.  (save-excursion
  2315.    (car (parse-partial-sexp (point-min) (point)))))
  2316.  
  2317. (defun verilog-in-comment-or-string-p ()
  2318.  "Return true if in a string or comment"
  2319.  (let ((state 
  2320.     (save-excursion
  2321.       (parse-partial-sexp (point-min) (point)))))
  2322.    (or (nth 3 state) (nth 4 state) (nth 7 state))) ; Inside string or comment
  2323.  )
  2324.  
  2325. (defun verilog-in-star-comment-p ()
  2326.  "Return true if in a star comment"
  2327.  (let ((state 
  2328.     (save-excursion
  2329.       (parse-partial-sexp (point-min) (point)))))
  2330.    (nth 4 state))
  2331.  )
  2332.  
  2333. (defun verilog-in-paren ()
  2334.  "Return true if in a parenthetical expression"
  2335.  (let ((state 
  2336.     (save-excursion
  2337.       (parse-partial-sexp (point-min) (point)))))
  2338.    (/= 0 (nth 0 state)))
  2339.  )
  2340.  
  2341. (defun verilog-skip-forward-comment-or-string ()
  2342.  "Return true if in a string or comment"
  2343.  (let ((state 
  2344.     (save-excursion
  2345.       (parse-partial-sexp (point-min) (point)))))
  2346.    (cond
  2347.     ((nth 3 state)            ;Inside string
  2348.      (goto-char (nth 3 state))
  2349.      t)
  2350.     ((nth 7 state)            ;Inside // comment
  2351.      (forward-line 1)
  2352.      t)
  2353.     ((nth 4 state)            ;Inside any comment (hence /**/)
  2354.      (search-forward "*/"))
  2355.     (t
  2356.      nil)
  2357.     )
  2358.    )
  2359.  )
  2360.  
  2361. (defun verilog-skip-backward-comment-or-string ()
  2362.  "Return true if in a string or comment"
  2363.  (let ((state 
  2364.     (save-excursion
  2365.       (parse-partial-sexp (point-min) (point)))))
  2366.    (cond
  2367.     ((nth 3 state)            ;Inside string
  2368.      (search-backward "\"")
  2369.      t)
  2370.     ((nth 7 state)            ;Inside // comment
  2371.      (search-backward "//")
  2372.      t)
  2373.     ((nth 4 state)            ;Inside /* */ comment
  2374.      (search-backward "/*")
  2375.      t)
  2376.     (t
  2377.      nil)
  2378.     )
  2379.    )
  2380.  )
  2381.  
  2382. (defun verilog-skip-forward-comment-p ()
  2383.   "If in comment, move to end and return true"
  2384.   (let (state)
  2385.     (progn 
  2386.       (setq state
  2387.         (save-excursion
  2388.           (parse-partial-sexp (point-min) (point))))
  2389.       (cond 
  2390.        ((nth 3 state)
  2391.     t)
  2392.        ((nth 7 state)            ;Inside // comment
  2393.     (end-of-line)
  2394.     (forward-char 1)
  2395.     t)
  2396.        ((nth 4 state)            ;Inside any comment
  2397.     t)
  2398.        (t
  2399.     nil)
  2400.        )
  2401.       )
  2402.     )
  2403.   )
  2404.  
  2405. (defun verilog-indent-line-relative ()
  2406.   "Cheap version of indent line that only looks at
  2407.   a few lines to determine indent level"
  2408.   (interactive)
  2409.   (let ((indent-str))
  2410.     (save-excursion
  2411.       (beginning-of-line)
  2412.       (if (looking-at "^[ \t]*$")
  2413.       (cond  ;- A blank line; No need to be too smart.
  2414.        ((bobp)
  2415.         (setq indent-str (list 'cpp 0)))
  2416.        ((verilog-continued-line)
  2417.         (let ((sp (point)))
  2418.           (if (verilog-continued-line)
  2419.           (progn (goto-char sp)
  2420.              (setq indent-str (list 'statement (verilog-indent-level))))
  2421.         (goto-char sp)
  2422.         (setq indent-str (list 'block (verilog-indent-level))))))
  2423.        (t
  2424.         (setq indent-str (verilog-calculate-indent))))
  2425.     (setq indent-str (verilog-calculate-indent))
  2426.     )
  2427.       )
  2428.     (verilog-do-indent indent-str)
  2429.     )
  2430.   )
  2431. (defun verilog-indent-line ()
  2432.   "Indent for special part of code."
  2433.   (if (looking-at verilog-directive-re)
  2434.       ;; We could nicely nest `ifdef's, but...
  2435.       (progn
  2436.     (delete-horizontal-space)
  2437.     (indent-to 0)
  2438.     (list 'cpp 0))            ; Return verilog-calculate-indent data
  2439.     (verilog-do-indent (verilog-calculate-indent)))
  2440.   )
  2441.  
  2442. (defun verilog-do-indent (indent-str)
  2443.   ""
  2444.   (let ((type (car indent-str))
  2445.     (ind (car (cdr indent-str))))
  2446.     (delete-horizontal-space)
  2447.     (cond 
  2448.      (; handle continued exp
  2449.       (eq type 'cexp)
  2450.       (let ((here (point)))
  2451.     (verilog-backward-syntactic-ws)
  2452.     (cond
  2453.      ((= (preceding-char) ?\,)
  2454.       (let* ( fst
  2455.           (column 
  2456.            (save-excursion
  2457.              (backward-char 1)
  2458.              (verilog-beg-of-statement)
  2459.              (setq fst (point))
  2460.              (if (looking-at verilog-declaration-re)
  2461.              (progn ;; we have multiple words
  2462.                (goto-char (match-end 0))
  2463.                (skip-chars-forward " \t")
  2464.                (if (= (following-char) ?\[)
  2465.                    (progn
  2466.                  (forward-char 1)
  2467.                  (backward-up-list -1)
  2468.                  (skip-chars-forward " \t")
  2469.                  )
  2470.                  )
  2471.                )
  2472.                (;; we have a single word
  2473.             goto-char fst)
  2474.                )
  2475.              (current-column)
  2476.              )
  2477.            )
  2478.           )
  2479.         (goto-char here)
  2480.         (beginning-of-line)
  2481.         (delete-horizontal-space)
  2482.         (indent-to  column))
  2483.       )
  2484.      ((= (preceding-char) ?\) )
  2485.       (goto-char here)
  2486.       (indent-to (eval (cdr (assoc type verilog-indent-alist))))
  2487.       )
  2488.      (t
  2489.       (goto-char here)
  2490.       (let ((val))
  2491.         (verilog-beg-of-statement)
  2492.         (if (verilog-re-search-forward "=[ \\t]*" here 'move)
  2493.         (setq val (current-column))
  2494.           (setq val (eval (cdr (assoc type verilog-indent-alist)))))
  2495.         (goto-char here)
  2496.         (indent-to val)
  2497.         )
  2498.       )
  2499.      )
  2500.     )
  2501.       )
  2502.      (; handle inside parenthetical expressions
  2503.       (eq type 'cparenexp)
  2504.       (let ((column (save-excursion
  2505.               (backward-up-list 1)
  2506.               (forward-char 1)
  2507.               (skip-chars-forward " \t")
  2508.               (current-column))))
  2509.     (beginning-of-line)
  2510.     (delete-horizontal-space)
  2511.     (indent-to  column)))
  2512.  
  2513.      (;-- Handle the ends
  2514.       (looking-at verilog-end-block-re )
  2515.       (if (eq type 'statement)
  2516.       (indent-to (- ind verilog-indent-level))         
  2517.     (indent-to ind)))
  2518.      (;-- Case -- maybe line 'em up
  2519.       (and (eq type 'case) (not (looking-at "^[ \t]*$")))
  2520.       (progn
  2521.     (cond
  2522.      ((looking-at "\\<endcase\\>")
  2523.       (indent-to ind))
  2524.      (t
  2525.       (indent-to (eval (cdr (assoc type verilog-indent-alist))))
  2526.       ))))
  2527.      
  2528.  
  2529.      (;-- defun
  2530.       (and (eq type 'defun)
  2531.         (looking-at verilog-zero-indent-re))
  2532.       (indent-to 0))
  2533.  
  2534.      (;-- declaration
  2535.       (and (or 
  2536.         (eq type 'defun)
  2537.         (eq type 'block))
  2538.        (looking-at verilog-declaration-re))
  2539.       (verilog-indent-declaration ind))
  2540.  
  2541.      (;-- Everything else
  2542.       t
  2543.       (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
  2544.     (indent-to val)
  2545.     ))
  2546.      )
  2547.     (if (looking-at "[ \t]+$")
  2548.     (skip-chars-forward " \t"))
  2549.     indent-str                ; Return indent data
  2550.     )
  2551. )
  2552.   
  2553. (defun verilog-indent-level ()
  2554.   "Return the indent-level the current statement has."
  2555.   (save-excursion
  2556.     (beginning-of-line)
  2557.     (skip-chars-forward " \t")
  2558.     (current-column)))
  2559.  
  2560.  
  2561. (defun verilog-case-indent-level ()
  2562.   "Return the indent-level the current statement has.
  2563. Do not count named blocks or case-statements."
  2564.   (save-excursion
  2565.     (skip-chars-forward " \t")
  2566.     (cond
  2567.      ((looking-at verilog-named-block-re)
  2568.       (current-column))
  2569.      ((and (not (looking-at verilog-case-re))
  2570.        (looking-at "^[^:;]+[ \t]*:"))
  2571.       (search-forward ":" nil t)
  2572.       (skip-chars-forward " \t")
  2573.       (current-column))
  2574.      (t
  2575.       (current-column)))))
  2576.  
  2577. (defun verilog-indent-comment (&optional arg)
  2578.   "Indent current line as comment.
  2579. If optional arg is non-nil, just return the
  2580. column number the line should be indented to."
  2581.   (let* ((stcol 
  2582.       (cond 
  2583.        ((verilog-in-star-comment-p)
  2584.         (save-excursion
  2585.           (re-search-backward "/\\*" nil t)
  2586.           (1+(current-column))))
  2587.        ( comment-column
  2588.          comment-column )
  2589.        (t
  2590.         (save-excursion
  2591.           (re-search-backward "//" nil t)
  2592.           (current-column)))
  2593.        )
  2594.       ))
  2595.     (if arg 
  2596.     (progn
  2597.       (delete-horizontal-space)
  2598.       (indent-to stcol))
  2599.       stcol
  2600.       )
  2601.     )
  2602.   )
  2603.  
  2604. ;;;
  2605.  
  2606. (defun verilog-pretty-declarations ()
  2607.   "Line up declarations arround point"
  2608.   (interactive)
  2609.   (save-excursion
  2610.     (if (progn
  2611.       (verilog-beg-of-statement-1)
  2612.       (looking-at verilog-declaration-re))
  2613.     (let* ((m1 (make-marker))
  2614.            (e) (r)
  2615.            (here (point))
  2616.            (start
  2617.         (progn
  2618.           (verilog-beg-of-statement-1)
  2619.           (while (looking-at verilog-declaration-re)
  2620.             (beginning-of-line)
  2621.             (setq e (point))
  2622.             (verilog-backward-syntactic-ws)
  2623.             (backward-char)
  2624.             (verilog-beg-of-statement-1))
  2625.           e))
  2626.            (end
  2627.         (progn
  2628.           (goto-char here)
  2629.           (verilog-end-of-statement)
  2630.           (setq e (point))    ;Might be on last line
  2631.           (verilog-forward-syntactic-ws)
  2632.           (while (looking-at verilog-declaration-re)
  2633.             (beginning-of-line)
  2634.             (verilog-end-of-statement)
  2635.             (setq e (point))
  2636.             (verilog-forward-syntactic-ws)
  2637.             )
  2638.           e))
  2639.            (edpos (set-marker (make-marker) end))
  2640.            (ind) 
  2641.            (base-ind 
  2642.         (progn
  2643.           (goto-char start)
  2644.           (verilog-do-indent (verilog-calculate-indent))
  2645.           (verilog-forward-ws&directives)
  2646.           (current-column)
  2647.           ))
  2648.            )
  2649.       (goto-char end)
  2650.       (goto-char start)
  2651.       (if (> (- end start) 100)
  2652.           (message "Lining up declarations..(please stand by)"))
  2653.       ;; Get the begining of line indent first
  2654.       (while (progn (setq e (marker-position edpos))
  2655.             (< (point) e))
  2656.         (delete-horizontal-space)
  2657.         (indent-to base-ind)
  2658.         (forward-line))
  2659.       ;; Now find biggest prefix
  2660.       (setq ind (verilog-get-lineup-indent start edpos))
  2661.       ;; Now indent each line.
  2662.       (goto-char start)
  2663.       (while (progn (setq e (marker-position edpos))
  2664.             (setq r (- e (point)))
  2665.             (> r 0))
  2666.         (setq e (point))
  2667.         (message "%d" r)
  2668.         (cond
  2669.          ((looking-at verilog-declaration-re-1)
  2670.           (let ((p (match-end 0)))
  2671.         (set-marker m1 p)
  2672.         (if (verilog-re-search-forward "\\[" p 'move)
  2673.             (progn
  2674.               (forward-char -1)
  2675.               (just-one-space)
  2676.               (goto-char (marker-position m1))
  2677.               (just-one-space)
  2678.               (indent-to ind)
  2679.               )
  2680.           (progn
  2681.             (just-one-space)
  2682.             (indent-to ind))
  2683.           )
  2684.         ))
  2685.          ((verilog-continued-line-1)
  2686.           (goto-char e)
  2687.           (delete-horizontal-space)
  2688.           (indent-to ind))
  2689.          (t     ; Must be comment or white space
  2690.           (goto-char e)
  2691.           (verilog-forward-ws&directives)
  2692.           (forward-line -1)
  2693.           )    
  2694.          )
  2695.         (forward-line 1)
  2696.         )
  2697.       (message "")
  2698.       )
  2699.       )
  2700.     )
  2701.   )
  2702. (defun verilog-indent-declaration (baseind)
  2703.   "Indent current lines as declaration, lining up the variable names
  2704.    based on previous declaration's indentation."
  2705.   (interactive)
  2706.   (let ((pos (point-marker))
  2707.     (lim (save-excursion 
  2708.            (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)" nil 'move)  
  2709.            (point)))
  2710.     (ind)
  2711.     (m1 (make-marker))
  2712.     )
  2713.     ;; Use previous declaration (in this module) as template.
  2714.     (if (verilog-re-search-backward verilog-declaration-re-1 lim t)
  2715.     (progn
  2716.       (goto-char (match-end 0))
  2717.       (setq ind (current-column))
  2718.       (goto-char pos)
  2719.       (beginning-of-line)
  2720.       (indent-to (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
  2721.       (if (looking-at verilog-declaration-re-2)
  2722.           (let ((p (match-end 0)))
  2723.         (set-marker m1 p)
  2724.         (if (verilog-re-search-forward "\\[" p 'move)
  2725.             (progn
  2726.               (forward-char -1)
  2727.               (just-one-space)
  2728.               (goto-char (marker-position m1))
  2729.               (just-one-space)
  2730.               (indent-to ind)
  2731.               )
  2732.           (progn
  2733.             (just-one-space)
  2734.             (indent-to ind)
  2735.             )
  2736.           )
  2737.         )
  2738.         )
  2739.       )
  2740.       (indent-to (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
  2741.       )
  2742.     (goto-char pos)
  2743.     )
  2744.   )
  2745.  
  2746. ;  "Return the indent level that will line up several lines within the region
  2747. ;from b to e nicely. The lineup string is str."
  2748. (defun verilog-get-lineup-indent (b edpos)
  2749.   (save-excursion
  2750.     (let ((ind 0) e)
  2751.       (goto-char b)
  2752.       ;; Get rightmost position
  2753.       (while (progn (setq e (marker-position edpos))
  2754.             (< (point) e))
  2755.     (if (verilog-re-search-forward verilog-declaration-re-1 e 'move)
  2756.         (progn
  2757.           (goto-char (match-end 0))
  2758.           (verilog-backward-syntactic-ws)
  2759.           (if (> (current-column) ind)
  2760.           (setq ind (current-column)))
  2761.           (goto-char (match-end 0)))))
  2762.       (if (> ind 0)
  2763.       (1+ ind)
  2764.     ;; No lineup-string found
  2765.     (goto-char b)
  2766.     (end-of-line)
  2767.     (skip-chars-backward " \t")
  2768.     (1+ (current-column))))))
  2769.  
  2770. ;;    A useful mode debugging aide
  2771. (defun verilog-comment-depth (type val)
  2772.   ""
  2773.   (save-excursion 
  2774.     (let 
  2775.     ((b (prog2
  2776.         (beginning-of-line)
  2777.         (point-marker)
  2778.           (end-of-line)))
  2779.      (e (point-marker)))          
  2780.       (if (re-search-backward " /\\* \[#-\]# \[a-z\]+ \[0-9\]+ ## \\*/" b t) 
  2781.       (progn 
  2782.         (replace-match " /* -#  ## */") 
  2783.         (end-of-line))
  2784.     (progn 
  2785.       (end-of-line)
  2786.       (insert " /* ##  ## */"))))
  2787.     (backward-char 6) 
  2788.     (insert 
  2789.      (format "%s %d" type val))
  2790.     )
  2791.   )
  2792. ;;; 
  2793. ;;;
  2794. ;;; Completion
  2795. ;;;
  2796. (defvar verilog-str nil)
  2797. (defvar verilog-all nil)
  2798. (defvar verilog-pred nil)
  2799. (defvar verilog-buffer-to-use nil)
  2800. (defvar verilog-flag nil)
  2801. (defvar verilog-toggle-completions nil
  2802.   "*Non-nil means \\<verilog-mode-map>\\[verilog-complete-word] should try all possible completions one by one.
  2803. Repeated use of \\[verilog-complete-word] will show you all of them.
  2804. Normally, when there is more than one possible completion,
  2805. it displays a list of all possible completions.")
  2806.  
  2807.  
  2808. (defvar verilog-type-keywords
  2809.   '("buf" "bufif0" "bufif1" "cmos" "defparam" "inout" "input"
  2810.     "integer" "nand" "nmos" "nor" "not" "notif0" "notif1" "or" "output" "parameter"
  2811.     "pmos" "pull0" "pull1" "pullup" "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
  2812.     "rtranif0" "rtranif1" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
  2813.     "triand" "trior" "trireg" "wand" "wire" "wor" "xnor" "xor" )
  2814.   "*Keywords for types used when completing a word in a declaration or parmlist.
  2815. \(eg. integer, real, char.)  The types defined within the Verilog program
  2816. will be completed runtime, and should not be added to this list.")
  2817.  
  2818. (defvar verilog-defun-keywords
  2819.   '("begin" "function" "task" "initial" "always" "assign" "posedge" "negedge" "endmodule")
  2820.   "*Keywords to complete when standing at first word of a line in declarative scope.
  2821. \(eg. initial, always, begin, assign.)
  2822. The procedures and variables defined within the Verilog program
  2823. will be completed runtime and should not be added to this list.")
  2824.  
  2825. (defvar verilog-block-keywords
  2826.   '("begin" "fork" "join" "case" "end" "if" "else" "for" "while" "repeat")
  2827.   "*Keywords to complete when standing at first word of a line in behavorial scope.
  2828. \(eg. begin, if, then, else, for, fork.)
  2829. The procedures and variables defined within the Verilog program
  2830. will be completed runtime and should not be added to this list.")
  2831.  
  2832. (defvar verilog-tf-keywords
  2833.   '("begin" "fork" "join" "case" "end" "endtask" "endfunction" "if" "else" "for" "while" "repeat")
  2834.   "*Keywords to complete when standing at first word of a line in a task or function scope.
  2835. \(eg. begin, if, then, else, for, fork.)
  2836. The procedures and variables defined within the Verilog program
  2837. will be completed runtime and should not be added to this list.")
  2838.  
  2839. (defvar verilog-case-keywords
  2840.   '("begin" "fork" "join" "case" "end" "endcase" "if" "else" "for" "repeat")
  2841.   "*Keywords to complete when standing at first word of a line in behavorial scope.
  2842. \(eg. begin, if, then, else, for, fork.)
  2843. The procedures and variables defined within the Verilog program
  2844. will be completed runtime and should not be added to this list.")
  2845.  
  2846. (defvar verilog-separator-keywords
  2847.   '("else" "then" "begin")
  2848.   "*Keywords to complete when NOT standing at the first word of a statement.
  2849. \(eg. else, then.) 
  2850. Variables and function names defined within the
  2851. Verilog program are completed runtime and should not be added to this list.")
  2852.  
  2853. (defun verilog-string-diff (str1 str2)
  2854.   "Return index of first letter where STR1 and STR2 differs."
  2855.   (catch 'done
  2856.     (let ((diff 0))
  2857.       (while t
  2858.     (if (or (> (1+ diff) (length str1))
  2859.         (> (1+ diff) (length str2)))
  2860.         (throw 'done diff))
  2861.     (or (equal (aref str1 diff) (aref str2 diff))
  2862.         (throw 'done diff))
  2863.     (setq diff (1+ diff))))))
  2864.  
  2865. ;; Calculate all possible completions for functions if argument is `function',
  2866. ;; completions for procedures if argument is `procedure' or both functions and
  2867. ;; procedures otherwise.
  2868.  
  2869. (defun verilog-func-completion (type)
  2870.   ;; Build regular expression for module/task/function names
  2871.   (if (string= verilog-str "")
  2872.       (setq verilog-str "[a-zA-Z_]"))
  2873.   (let ((verilog-str (concat (cond
  2874.                  ((eq type 'module) "\\<\\(module\\)\\s +")
  2875.                  ((eq type 'tf) "\\<\\(task\\|function\\)\\s +")
  2876.                  (t "\\<\\(task\\|function\\|module\\)\\s +"))
  2877.                 "\\<\\(" verilog-str "[a-zA-Z0-9_.]*\\)\\>"))
  2878.     match)
  2879.     
  2880.     (if (not (looking-at verilog-defun-re))
  2881.     (verilog-re-search-backward verilog-defun-re nil t))
  2882.     (forward-char 1)
  2883.  
  2884.     ;; Search through all reachable functions
  2885.     (goto-char (point-min))
  2886.     (while (verilog-re-search-forward verilog-str (point-max) t)
  2887.       (progn (setq match (buffer-substring (match-beginning 2)
  2888.                        (match-end 2)))
  2889.          (if (or (null verilog-pred)
  2890.              (funcall verilog-pred match))
  2891.          (setq verilog-all (cons match verilog-all)))))
  2892.     (if (match-beginning 0)
  2893.     (goto-char (match-beginning 0)))))
  2894.  
  2895. (defun verilog-get-completion-decl ()
  2896.   ;; Macro for searching through current declaration (var, type or const)
  2897.   ;; for matches of `str' and adding the occurence tp `all'
  2898.   (let ((end (save-excursion (verilog-declaration-end)
  2899.                  (point)))
  2900.     match)
  2901.     ;; Traverse lines
  2902.     (while (< (point) end)
  2903.       (if (verilog-re-search-forward verilog-declaration-re-1 (verilog-get-end-of-line) t)
  2904.       ;; Traverse current line
  2905.       (while (and (verilog-re-search-forward 
  2906.                (concat "\\((\\|\\<\\(var\\|type\\|const\\)\\>\\)\\|" 
  2907.                    verilog-symbol-re)
  2908.                (verilog-get-beg-of-line) t)
  2909.               (not (match-end 1)))
  2910.         (setq match (buffer-substring (match-beginning 0) (match-end 0)))
  2911.         (if (string-match (concat "\\<" verilog-str) match)
  2912.         (if (or (null verilog-pred)
  2913.             (funcall verilog-pred match))
  2914.             (setq verilog-all (cons match verilog-all))))))
  2915.       (if (verilog-re-search-forward "\\<record\\>" (verilog-get-end-of-line) t)
  2916.       (verilog-declaration-end)
  2917.     (forward-line 1)))))
  2918.  
  2919. (defun verilog-type-completion ()
  2920.   "Calculate all possible completions for types."
  2921.   (let ((start (point))
  2922.     goon)
  2923.     ;; Search for all reachable type declarations
  2924.     (while (or (verilog-beg-of-defun)
  2925.            (setq goon (not goon)))
  2926.       (save-excursion
  2927.     (if (and (< start (prog1 (save-excursion (verilog-end-of-defun)
  2928.                          (point))
  2929.                 (forward-char 1)))
  2930.          (verilog-re-search-forward
  2931.           "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
  2932.           start t)
  2933.          (not (match-end 1)))
  2934.         ;; Check current type declaration
  2935.         (verilog-get-completion-decl))))))
  2936.  
  2937. (defun verilog-var-completion ()
  2938.   "Calculate all possible completions for variables (or constants)."
  2939.   nil)
  2940. ;  Not done yet; in 1.99 perhaps
  2941. ;  (let ((start (point))
  2942. ;    goon twice)
  2943. ;    ;; Search for all reachable var declarations
  2944. ;    (while (or (verilog-beg-of-defun)
  2945. ;           (setq goon (not goon)))
  2946. ;      (save-excursion
  2947. ;    (if (> start (prog1 (save-excursion (verilog-end-of-defun)
  2948. ;                        (point))))
  2949. ;        () ; Declarations not reacable
  2950. ;      (cond ((and (verilog-re-search-forward  verilog-declaration-re start t)
  2951. ;              ;; Check var/const declarations
  2952. ;              (verilog-get-completion-decl)))))))))
  2953.  
  2954.  
  2955. (defun verilog-keyword-completion (keyword-list)
  2956.   "Give list of all possible completions of keywords in KEYWORD-LIST."
  2957.   (mapcar '(lambda (s) 
  2958.          (if (string-match (concat "\\<" verilog-str) s)
  2959.          (if (or (null verilog-pred)
  2960.              (funcall verilog-pred s))
  2961.              (setq verilog-all (cons s verilog-all)))))
  2962.       keyword-list))
  2963.  
  2964. ;; Function passed to completing-read, try-completion or
  2965. ;; all-completions to get completion on STR. If predicate is non-nil,
  2966. ;; it must be a function to be called for every match to check if this
  2967. ;; should really be a match. If flag is t, the function returns a list
  2968. ;; of all possible completions. If it is nil it returns a string, the
  2969. ;; longest possible completion, or t if STR is an exact match. If flag
  2970. ;; is 'lambda, the function returns t if STR is an exact match, nil
  2971. ;; otherwise.
  2972.  
  2973. (defun verilog-completion (verilog-str verilog-pred verilog-flag)
  2974.   (save-excursion
  2975.     (let ((verilog-all nil))
  2976.       ;; Set buffer to use for searching labels. This should be set
  2977.       ;; within functions which use verilog-completions
  2978.       (set-buffer verilog-buffer-to-use)
  2979.  
  2980.       ;; Determine what should be completed
  2981.       (let ((state (car (verilog-calculate-indent))))
  2982.     (cond ((eq state 'defun)
  2983.            (save-excursion (verilog-var-completion))
  2984.            (verilog-func-completion 'module)
  2985.            (verilog-keyword-completion verilog-defun-keywords))
  2986.  
  2987.           ((eq state 'block)
  2988.            (save-excursion (verilog-var-completion))
  2989.            (verilog-func-completion 'tf)
  2990.            (verilog-keyword-completion verilog-block-keywords))
  2991.  
  2992.           ((eq state 'case)
  2993.            (save-excursion (verilog-var-completion))
  2994.            (verilog-func-completion 'tf)
  2995.            (verilog-keyword-completion verilog-case-keywords))
  2996.  
  2997.           ((eq state 'tf)
  2998.            (save-excursion (verilog-var-completion))
  2999.            (verilog-func-completion 'tf)
  3000.            (verilog-keyword-completion verilog-tf-keywords))
  3001.       
  3002.           (t;--Anywhere else
  3003.            (save-excursion (verilog-var-completion))
  3004.            (verilog-func-completion 'both)
  3005.            (verilog-keyword-completion verilog-separator-keywords))))
  3006.       
  3007.       ;; Now we have built a list of all matches. Give response to caller
  3008.       (verilog-completion-response))))
  3009.  
  3010. (defun verilog-completion-response ()
  3011.   (cond ((or (equal verilog-flag 'lambda) (null verilog-flag))
  3012.      ;; This was not called by all-completions
  3013.      (if (null verilog-all)
  3014.          ;; Return nil if there was no matching label
  3015.          nil
  3016.        ;; Get longest string common in the labels
  3017.        (let* ((elm (cdr verilog-all))
  3018.           (match (car verilog-all))
  3019.           (min (length match))
  3020.           tmp)
  3021.          (if (string= match verilog-str)
  3022.          ;; Return t if first match was an exact match
  3023.          (setq match t)
  3024.            (while (not (null elm))
  3025.          ;; Find longest common string
  3026.          (if (< (setq tmp (verilog-string-diff match (car elm))) min)
  3027.              (progn
  3028.                (setq min tmp)
  3029.                (setq match (substring match 0 min))))
  3030.          ;; Terminate with match=t if this is an exact match
  3031.          (if (string= (car elm) verilog-str)
  3032.              (progn
  3033.                (setq match t)
  3034.                (setq elm nil))
  3035.            (setq elm (cdr elm)))))
  3036.          ;; If this is a test just for exact match, return nil ot t
  3037.          (if (and (equal verilog-flag 'lambda) (not (equal match 't)))
  3038.          nil
  3039.            match))))
  3040.     ;; If flag is t, this was called by all-completions. Return
  3041.     ;; list of all possible completions
  3042.     (verilog-flag
  3043.      verilog-all)))
  3044.  
  3045. (defvar verilog-last-word-numb 0)
  3046. (defvar verilog-last-word-shown nil)
  3047. (defvar verilog-last-completions nil)
  3048.  
  3049. (defun verilog-complete-word ()
  3050.   "Complete word at current point.
  3051. \(See also `verilog-toggle-completions', `verilog-type-keywords',
  3052. `verilog-start-keywords' and `verilog-separator-keywords'.)"
  3053.   (interactive)
  3054.   (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
  3055.      (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
  3056.      (verilog-str (buffer-substring b e))
  3057.      ;; The following variable is used in verilog-completion
  3058.      (verilog-buffer-to-use (current-buffer))
  3059.      (allcomp (if (and verilog-toggle-completions
  3060.                (string= verilog-last-word-shown verilog-str))
  3061.               verilog-last-completions
  3062.             (all-completions verilog-str 'verilog-completion)))
  3063.      (match (if verilog-toggle-completions
  3064.             "" (try-completion
  3065.             verilog-str (mapcar '(lambda (elm)
  3066.                           (cons elm 0)) allcomp)))))
  3067.     ;; Delete old string
  3068.     (delete-region b e)
  3069.  
  3070.     ;; Toggle-completions inserts whole labels
  3071.     (if verilog-toggle-completions
  3072.     (progn
  3073.       ;; Update entry number in list
  3074.       (setq verilog-last-completions allcomp
  3075.         verilog-last-word-numb 
  3076.         (if (>= verilog-last-word-numb (1- (length allcomp)))
  3077.             0
  3078.           (1+ verilog-last-word-numb)))
  3079.       (setq verilog-last-word-shown (elt allcomp verilog-last-word-numb))
  3080.       ;; Display next match or same string if no match was found
  3081.       (if (not (null allcomp))
  3082.           (insert "" verilog-last-word-shown)
  3083.         (insert "" verilog-str)
  3084.         (message "(No match)")))
  3085.       ;; The other form of completion does not necessarly do that.
  3086.  
  3087.       ;; Insert match if found, or the original string if no match
  3088.       (if (or (null match) (equal match 't))
  3089.       (progn (insert "" verilog-str)
  3090.          (message "(No match)"))
  3091.     (insert "" match))
  3092.       ;; Give message about current status of completion
  3093.       (cond ((equal match 't)
  3094.          (if (not (null (cdr allcomp)))
  3095.          (message "(Complete but not unique)")
  3096.            (message "(Sole completion)")))
  3097.         ;; Display buffer if the current completion didn't help 
  3098.         ;; on completing the label.
  3099.         ((and (not (null (cdr allcomp))) (= (length verilog-str)
  3100.                         (length match)))
  3101.          (with-output-to-temp-buffer "*Completions*"
  3102.            (display-completion-list allcomp))
  3103.          ;; Wait for a keypress. Then delete *Completion*  window
  3104.          (momentary-string-display "" (point))
  3105.          (delete-window (get-buffer-window (get-buffer "*Completions*")))
  3106.          )))))
  3107.  
  3108. (defun verilog-show-completions ()
  3109.   "Show all possible completions at current point."
  3110.   (interactive)
  3111.   (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
  3112.      (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
  3113.      (verilog-str (buffer-substring b e))
  3114.      ;; The following variable is used in verilog-completion
  3115.      (verilog-buffer-to-use (current-buffer))
  3116.      (allcomp (if (and verilog-toggle-completions
  3117.                (string= verilog-last-word-shown verilog-str))
  3118.               verilog-last-completions
  3119.             (all-completions verilog-str 'verilog-completion))))
  3120.     ;; Show possible completions in a temporary buffer.
  3121.     (with-output-to-temp-buffer "*Completions*"
  3122.       (display-completion-list allcomp))
  3123.     ;; Wait for a keypress. Then delete *Completion*  window
  3124.     (momentary-string-display "" (point))
  3125.     (delete-window (get-buffer-window (get-buffer "*Completions*")))))
  3126.  
  3127.  
  3128. (defun verilog-get-default-symbol ()
  3129.   "Return symbol around current point as a string."
  3130.   (save-excursion
  3131.     (buffer-substring (progn
  3132.             (skip-chars-backward " \t")
  3133.             (skip-chars-backward "a-zA-Z0-9_")
  3134.             (point))
  3135.               (progn
  3136.             (skip-chars-forward "a-zA-Z0-9_")
  3137.             (point)))))
  3138.  
  3139. (defun verilog-build-defun-re (str &optional arg)
  3140.   "Return function/task/module starting with STR as regular expression.
  3141. With optional second arg non-nil, STR is the complete name of the instruction."
  3142.   (if arg
  3143.       (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "\\)\\>")
  3144.     (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>")))
  3145.  
  3146. ;; Function passed to completing-read, try-completion or
  3147. ;; all-completions to get completion on any function name. If
  3148. ;; predicate is non-nil, it must be a function to be called for every
  3149. ;; match to check if this should really be a match. If flag is t, the
  3150. ;; function returns a list of all possible completions. If it is nil
  3151. ;; it returns a string, the longest possible completion, or t if STR
  3152. ;; is an exact match. If flag is 'lambda, the function returns t if
  3153. ;; STR is an exact match, nil otherwise.
  3154.  
  3155. (defun verilog-comp-defun (verilog-str verilog-pred verilog-flag)
  3156.   (save-excursion
  3157.     (let ((verilog-all nil)
  3158.       match)
  3159.  
  3160.       ;; Set buffer to use for searching labels. This should be set
  3161.       ;; within functions which use verilog-completions
  3162.       (set-buffer verilog-buffer-to-use)
  3163.  
  3164.       (let ((verilog-str verilog-str))
  3165.     ;; Build regular expression for functions
  3166.     (if (string= verilog-str "")
  3167.         (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]"))
  3168.       (setq verilog-str (verilog-build-defun-re verilog-str)))
  3169.     (goto-char (point-min))
  3170.       
  3171.     ;; Build a list of all possible completions
  3172.     (while (verilog-re-search-forward verilog-str nil t)
  3173.       (setq match (buffer-substring (match-beginning 2) (match-end 2)))
  3174.       (if (or (null verilog-pred)
  3175.           (funcall verilog-pred match))
  3176.           (setq verilog-all (cons match verilog-all)))))
  3177.  
  3178.       ;; Now we have built a list of all matches. Give response to caller
  3179.       (verilog-completion-response))))
  3180.  
  3181. (defun verilog-goto-defun ()
  3182.   "Move to specified Verilog module/task/function.
  3183. The default is a name found in the buffer around point."
  3184.   (interactive)
  3185.   (let* ((default (verilog-get-default-symbol))
  3186.      ;; The following variable is used in verilog-comp-function
  3187.      (verilog-buffer-to-use (current-buffer))
  3188.      (default (if (verilog-comp-defun default nil 'lambda)
  3189.               default ""))
  3190.      (label (if (not (string= default ""))
  3191.             ;; Do completion with default
  3192.             (completing-read (concat "Label: (default " default ") ")
  3193.                      'verilog-comp-defun nil t "")
  3194.           ;; There is no default value. Complete without it
  3195.           (completing-read "Label: "
  3196.                    'verilog-comp-defun nil t ""))))
  3197.     ;; If there was no response on prompt, use default value
  3198.     (if (string= label "")
  3199.     (setq label default))
  3200.     ;; Goto right place in buffer if label is not an empty string
  3201.     (or (string= label "")
  3202.     (progn
  3203.       (goto-char (point-min))
  3204.       (re-search-forward (verilog-build-defun-re label t))
  3205.       (beginning-of-line)))))
  3206. (defun verilog-showscopes ()
  3207.   "list all scopes in this module"
  3208.   (interactive)
  3209.   (let (
  3210.         (buffer (current-buffer))
  3211.     (linenum 1)
  3212.     (nlines 0)
  3213.     (first 1)
  3214.     (prevpos (point-min))
  3215.         (final-context-start (make-marker))
  3216.     (regexp "\\(module\\s-+\\w+\\s-*(\\)\\|\\(\\w+\\s-+\\w+\\s-*(\\)")
  3217.     )
  3218.     (with-output-to-temp-buffer "*Occur*"
  3219.       (save-excursion
  3220.     (message (format "Searching for %s ..." regexp))
  3221.     ;; Find next match, but give up if prev match was at end of buffer.
  3222.     (while (and (not (= prevpos (point-max)))
  3223.             (verilog-re-search-forward regexp nil t))
  3224.       (goto-char (match-beginning 0))
  3225.       (beginning-of-line)
  3226.       (save-match-data
  3227.             (setq linenum (+ linenum (count-lines prevpos (point)))))
  3228.       (setq prevpos (point))
  3229.       (goto-char (match-end 0))
  3230.       (let* ((start (save-excursion
  3231.               (goto-char (match-beginning 0))
  3232.               (forward-line (if (< nlines 0) nlines (- nlines)))
  3233.               (point)))
  3234.          (end (save-excursion
  3235.             (goto-char (match-end 0))
  3236.             (if (> nlines 0)
  3237.                 (forward-line (1+ nlines))
  3238.                 (forward-line 1))
  3239.             (point)))
  3240.          (tag (format "%3d" linenum))
  3241.          (empty (make-string (length tag) ?\ ))
  3242.          tem)
  3243.         (save-excursion
  3244.           (setq tem (make-marker))
  3245.           (set-marker tem (point))
  3246.           (set-buffer standard-output)
  3247.           (setq occur-pos-list (cons tem occur-pos-list))
  3248.           (or first (zerop nlines)
  3249.           (insert "--------\n"))
  3250.           (setq first nil)
  3251.           (insert-buffer-substring buffer start end)
  3252.           (backward-char (- end start))
  3253.           (setq tem (if (< nlines 0) (- nlines) nlines))
  3254.           (while (> tem 0)
  3255.         (insert empty ?:)
  3256.         (forward-line 1)
  3257.         (setq tem (1- tem)))
  3258.           (let ((this-linenum linenum))
  3259.         (set-marker final-context-start
  3260.                 (+ (point) (- (match-end 0) (match-beginning 0))))
  3261.         (while (< (point) final-context-start)
  3262.           (if (null tag)
  3263.               (setq tag (format "%3d" this-linenum)))
  3264.           (insert tag ?:)))))))
  3265.       (set-buffer-modified-p nil))))
  3266.  
  3267. (defun verilog-submit-bug-report ()
  3268.   "Submit via mail a bug report on lazy-lock.el."
  3269.   (interactive)
  3270.   (let ((reporter-prompt-for-summary-p t))
  3271.     (reporter-submit-bug-report 
  3272.      "verilog-mode-bugs@silicon-sorcery.com" 
  3273.      (concat "verilog-mode v" (substring verilog-mode-version 12 -3))
  3274.      '(verilog-indent-level 
  3275.        verilog-indent-level-module 
  3276.        verilog-indent-level-declaration
  3277.        verilog-indent-level-behavorial 
  3278.        verilog-case-indent 
  3279.        verilog-auto-newline 
  3280.        verilog-auto-indent-on-newline 
  3281.        verilog-tab-always-indent 
  3282.        verilog-auto-endcomments 
  3283.        verilog-minimum-comment-distance 
  3284.        verilog-indent-begin-after-if 
  3285.        verilog-auto-lineup)
  3286.      nil nil
  3287.      (concat "Hi Mac,
  3288.  
  3289. I want to report a bug.  I've read the `Bugs' section of `Info' on
  3290. Emacs, so I know how to make a clear and unambiguous report.  To get
  3291. to that Info section, I typed
  3292.  
  3293. M-x info RET m " invocation-name " RET m bugs RET
  3294.  
  3295. Before I go further, I want to say that Verilog mode has changed my life.
  3296. I save so much time, my files are colored nicely, my co workers respect 
  3297. my coding ability... until now.  I'd really appreciate anything you 
  3298. could do to help me out with this minor deficiency in the product.
  3299.  
  3300. To reproduce the bug, start a fresh Emacs via " invocation-name "
  3301. -no-init-file -no-site-file'.  In a new buffer, in verilog mode, type
  3302. the code included below.
  3303.  
  3304. Given those lines, I expected [[Fill in here]] to happen; 
  3305. but instead, [[Fill in here]] happens!.
  3306.  
  3307. == The code: =="))))
  3308.  
  3309. ;;; verilog.el ends here
  3310.